﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ZTD2PWV
{
public class gtm
    {
        private double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
        private double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };
        private double[] at_mean = new double[55] { 1.57366356718047, -7.23117076409196, -0.609165730133987, 1.55459515487181, 2.12616131885469, 0.226345037276564, -0.126944701222952, -2.19386351426612, 0.382146294605515, -0.0598842308948210, -6.35354344762160, 2.57805587341979, -0.714876701152450, -0.0106479066097332, -0.0354843948199196, 11.8503267070760, -0.466021793670618, 0.316830837182225, 0.100036370697244, -0.00575160036093251, 0.00432180140789038, -3.51168854392692, -1.36526456676358, 0.107167855911301, -0.0812800924150469, 0.00172552719493611, -0.000149608358710444, 1.87559307212429e-05, -2.37737987928828, 0.0198663853746460, -0.134140789124229, 0.0213838742360449, 0.00104314814190517, -0.000609936355923425, 7.25192357323046e-05, -2.95975884515015e-05, 0.955857181803743, 0.116528854209815, 0.0181386569286297, 0.00757362756117942, -0.00193321274299353, 0.000419166579104328, -1.57109424242587e-05, -1.99177441792556e-06, -1.51525511060485e-07, -0.550124560038650, 0.00817810525279616, 0.0178995684288735, -0.00672793145521911, 0.000734479530663568, -3.80618409522473e-05, 1.89862587858041e-06, 6.51032083982124e-07, -3.93866777863108e-08, -5.44589391442153e-08 };



        double[] bt_mean = new double[55] { +0.0000e+000, +0.0000e+000, +1.0210e+000, +0.0000e+000, +6.0194e-001, +1.2292e-001, +0.0000e+000, -4.2184e-001, +1.8230e-001, +4.2329e-002, +0.0000e+000, +9.3312e-002, +9.5346e-002, -1.9724e-003, +5.8776e-003, +0.0000e+000, -2.0940e-001, +3.4199e-002, -5.7672e-003, -2.1590e-003, +5.6815e-004, +0.0000e+000, +2.2858e-001, +1.2283e-002, -9.3679e-003, -1.4233e-003, -1.5962e-004, +4.0160e-005, +0.0000e+000, +3.6353e-002, -9.4263e-004, -3.6762e-003, +5.8608e-005, -2.6391e-005, +3.2095e-006, -1.1605e-006, +0.0000e+000, +1.6306e-001, +1.3293e-002, -1.1395e-003, +5.1097e-005, +3.3977e-005, +7.6449e-006, -1.7602e-007, -7.6558e-008, +0.0000e+000, -4.5415e-002, -1.8027e-002, +3.6561e-004, -1.1274e-004, +1.3047e-005, +2.0001e-006, -1.5152e-007, -2.7807e-008, +7.7491e-009 };
        double[] at_amp = new double[55] { -1.8654e+000, -9.0041e+000, -1.2974e-001, -3.6053e+000, +2.0284e-002, +2.1872e-001, -1.3015e+000, +4.0355e-001, +2.2216e-001, -4.0605e-003, +1.9623e+000, +4.2887e-001, +2.1437e-001, -1.0061e-002, -1.1368e-003, -6.9235e-002, +5.6758e-001, +1.1917e-001, -7.0765e-003, +3.0017e-004, +3.0601e-004, +1.6559e+000, +2.0722e-001, +6.0013e-002, +1.7023e-004, -9.2424e-004, +1.1269e-005, -6.9911e-006, -2.0886e+000, -6.7879e-002, -8.5922e-004, -1.6087e-003, -4.5549e-005, +3.3178e-005, -6.1715e-006, -1.4446e-006, -3.7210e-001, +1.5775e-001, -1.7827e-003, -4.4396e-004, +2.2844e-004, -1.1215e-005, -2.1120e-006, -9.6421e-007, -1.4170e-008, +7.8720e-001, -4.4238e-002, -1.5120e-003, -9.4119e-004, +4.0645e-006, -4.9253e-006, -1.8656e-006, -4.0736e-007, -4.9594e-008, +1.6134e-009 };
        double[] bt_amp = new double[55] { +0.0000e+000, +0.0000e+000, -8.9895e-001, +0.0000e+000, -1.0790e+000, -1.2699e-001, +0.0000e+000, -5.9033e-001, +3.4865e-002, -3.2614e-002, +0.0000e+000, -2.4310e-002, +1.5607e-002, -2.9833e-002, -5.9048e-003, +0.0000e+000, +2.8383e-001, +4.0509e-002, -1.8834e-002, -1.2654e-003, -1.3794e-004, +0.0000e+000, +1.3306e-001, +3.4960e-002, -3.6799e-003, -3.5626e-004, +1.4814e-004, +3.7932e-006, +0.0000e+000, +2.0801e-001, +6.5640e-003, -3.4893e-003, -2.7395e-004, +7.4296e-005, -7.9927e-006, -1.0277e-006, +0.0000e+000, +3.6515e-002, -7.4319e-003, -6.2873e-004, -8.2461e-005, +3.1095e-005, -5.3860e-007, -1.2055e-007, -1.1517e-007, +0.0000e+000, +3.1404e-002, +1.5580e-002, -1.1428e-003, +3.3529e-005, +1.0387e-005, -1.9378e-006, -2.7327e-007, +7.5833e-009, -9.2323e-009 };



        /// <summary>
        /// 一代GWMT模型
        /// </summary>
        /// <param name="doy">年积日</param>
        /// <param name="lat">纬度（度）</param>
        /// <param name="lon">经度（度）</param>
        /// <param name="h">大地高（米）</param>
        /// <returns></returns>
        public static double GetTm_GWMT(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { +2.8016e+002, -5.6872e+000, +3.8909e-002, -1.7315e+001, +3.2029e+000, +2.0950e-001, -4.2781e-001, -1.9802e+000, +3.2656e-001, -6.5104e-002, -9.4437e+000, +2.7176e+000, -7.2632e-001, -1.0385e-003, -3.6031e-002, +1.2180e+001, -3.8980e-001, +3.3896e-001, +1.0117e-001, -2.0203e-003, +4.0536e-003, -3.2068e+000, -1.2381e+000, +1.3275e-001, -7.7234e-002, +1.9781e-003, -1.8740e-005, +2.2050e-005, -1.8464e+000, +2.6792e-001, -9.0697e-002, +2.4401e-002, +8.1835e-004, -6.1739e-004, +7.5870e-005, -2.9726e-005, -1.0808e+000, +1.5702e-001, +3.0995e-002, +9.8326e-003, -1.9646e-003, +3.9563e-004, -1.7089e-005, -6.0835e-007, -2.4168e-007, -9.9527e-001, +1.6400e-001, +1.7958e-002, -6.3732e-003, +5.7614e-004, -5.2672e-005, +1.8227e-006, +1.1834e-006, -2.5700e-008, -4.3692e-008 };
            double[] atm_amp = new double[55] { -2.7728e+000, -7.5283e+000, +2.1999e-002, -2.5937e+000, -1.6267e-001, -7.4794e-002, -1.3088e-001, +9.8054e-001, +1.3614e-001, +6.2514e-002, +4.1121e-001, +2.6168e-001, +3.3232e-001, -8.2088e-003, +2.2860e-002, -1.7374e+000, +4.3731e-001, -4.3279e-002, -4.0835e-002, +2.1399e-004, +1.6214e-003, +4.6134e+000, +5.6725e-001, +1.8581e-002, +2.7329e-002, -4.7682e-003, -1.4869e-005, +5.8632e-005, +6.2653e-003, -3.1505e-001, +4.2535e-003, +1.8852e-003, -5.5224e-004, +1.7282e-004, -8.3607e-005, -5.7291e-006, -2.1930e+000, -1.2753e-001, -7.2903e-003, -2.6333e-003, +8.4671e-004, -1.0379e-005, +4.5349e-007, +1.4445e-006, +1.3709e-008, +6.2457e-001, +8.6543e-002, +3.2264e-003, -9.6226e-005, -5.8426e-005, +5.1657e-007, -7.8229e-007, +4.3494e-007, +4.8682e-008, +8.8366e-009 };
            double[] btm_mean = new double[55]{+0.0000e+000,+0.0000e+000,-1.0560e+000,+0.0000e+000,+4.0234e+000,
    +1.1051e+000,+0.0000e+000,-7.2625e+000,-2.1040e-001,-3.4823e-001,
    +0.0000e+000,+4.3705e+000,+7.7373e-001,+1.4833e-002,+5.2877e-003,
    +0.0000e+000,+3.9907e-001,-5.1635e-001,+3.6154e-002,+4.8566e-003,
    +2.0707e-003,+0.0000e+000,-1.9797e+000,+2.2000e-001,-9.3264e-003,
    -7.0120e-003,+4.9429e-004,-2.5810e-004,+0.0000e+000,+8.5808e-001,
    -7.3579e-003,-2.0269e-002,+4.3399e-003,-2.3579e-004,-1.7385e-005,
    -8.5941e-007,+0.0000e+000,+5.6363e-001,-3.2139e-003,+1.2155e-002,
    -1.4205e-003,-2.4200e-004,+4.7961e-005,-4.0606e-006,+4.5887e-007,
    +0.0000e+000,-4.7424e-001,-1.9732e-002,-1.9259e-003,+1.7334e-004,
    +8.1834e-005,-1.8045e-006,+5.7849e-007,+2.0996e-007,-3.1102e-008};
            double[] btm_amp = new double[55]{+0.0000e+000,+0.0000e+000,-1.4327e+000,+0.0000e+000,-1.5105e+000,
    -8.9129e-001,+0.0000e+000,+4.9271e-001,-4.0104e-002,-3.4000e-002,
    +0.0000e+000,-3.2911e-001,+2.6720e-001,-3.7570e-002,-1.5440e-002,
    +0.0000e+000,-3.4506e-001,+2.4431e-001,-2.8199e-002,+2.1516e-003,
    +1.5038e-003,+0.0000e+000,+6.0108e-001,-8.8919e-002,-1.1045e-002,
    +2.2734e-003,-3.5372e-004,+2.0760e-004,+0.0000e+000,+3.1097e-001,
    -8.3211e-002,-2.6425e-003,-5.8182e-005,-5.7868e-005,-1.3714e-006,
    +2.0388e-005,+0.0000e+000,-3.8079e-001,+3.3248e-002,+4.1894e-003,
    -4.9002e-004,+7.4654e-005,-1.6207e-005,+2.3754e-006,+6.0765e-008,
    +0.0000e+000,+1.8702e-001,+1.0714e-003,-8.9522e-004,+2.6448e-005,
    -4.5731e-005,+1.0969e-006,+9.6145e-008,-2.5005e-007,-7.5742e-009};
            double alpha2 = -0.0041;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata = ata + (atm_amp[i - 1] * aP[i - 1] + btm_amp[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata * Math.Cos((doy + 1 - 28) / 365.25 * 2 * Math.PI);
            double Tm = Tm0 + alpha2 * hort;
            return Tm;





        }

        public static double GetTm_GPTB(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double temp = 0;
            double pres = 0;
            double undu = 0;
            refGPT(doy, lat, lon, h, ref pres, ref temp, ref undu);
            return (70.2 + 0.72 * temp);
        }
        /// <summary>
        /// 需要输入温度单位为K
        /// </summary>
        /// <param name="temp">温度（K）</param>
        /// <returns></returns>
        public static double GetTm_Bevis(double temp)
        {
            return (70.2 + 0.72 * temp);
        }

        public static double GetTm_dGWMT(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { 1.57366356718047, -7.23117076409196, -0.609165730133987, 1.55459515487181, 2.12616131885469, 0.226345037276564, -0.126944701222952, -2.19386351426612, 0.382146294605515, -0.0598842308948210, -6.35354344762160, 2.57805587341979, -0.714876701152450, -0.0106479066097332, -0.0354843948199196, 11.8503267070760, -0.466021793670618, 0.316830837182225, 0.100036370697244, -0.00575160036093251, 0.00432180140789038, -3.51168854392692, -1.36526456676358, 0.107167855911301, -0.0812800924150469, 0.00172552719493611, -0.000149608358710444, 1.87559307212429e-05, -2.37737987928828, 0.0198663853746460, -0.134140789124229, 0.0213838742360449, 0.00104314814190517, -0.000609936355923425, 7.25192357323046e-05, -2.95975884515015e-05, 0.955857181803743, 0.116528854209815, 0.0181386569286297, 0.00757362756117942, -0.00193321274299353, 0.000419166579104328, -1.57109424242587e-05, -1.99177441792556e-06, -1.51525511060485e-07, -0.550124560038650, 0.00817810525279616, 0.0178995684288735, -0.00672793145521911, 0.000734479530663568, -3.80618409522473e-05, 1.89862587858041e-06, 6.51032083982124e-07, -3.93866777863108e-08, -5.44589391442153e-08 };
            double[] atm_amp = new double[55] { -1.41626229909203, -1.05580617080476, 0.122554279781398, 0.0759038404378430, -0.204075190747293, -0.181036372518872, 0.753871154370160, 0.645297191807653, -0.0178433681622215, 0.0533931704690902, -1.16740084409485, -0.0134138954176516, 0.167707055393248, -0.00244602424365899, 0.0230256400744269, -1.51307915819262, 0.0444099839736695, -0.123527272557302, -0.0338497700371705, 0.000290460052344472, 0.00154904075903280, 3.47412221457157, 0.395734596597652, -0.0229149483471681, 0.0262391856702840, -0.00408588270453072, -3.58274499685277e-05, 5.83764761140604e-05, 1.38367082449436, -0.257116125310994, 0.000763392576117534, 0.00309430217523959, -0.000490482429666817, 0.000123833599647624, -7.91749268513329e-05, -4.98357118915728e-06, -1.89956587956863, -0.236648041134763, -0.00535427106759014, -0.00205526371214927, 0.000685357039040421, -1.14171854179664e-06, 3.04184779106088e-06, 2.15260224064159e-06, 5.47198354093143e-08, 0.0722610536470926, 0.110912838287793, 0.00493801599382021, 0.000459474815927419, -6.46356938355539e-05, 4.96472254176801e-06, 5.44861580407214e-07, 6.73458715467746e-07, 1.10522770822033e-07, 1.42569431359615e-09 };
            double[] btm_mean = new double[55] { 0, 0, -1.63948690891486, 0, 3.58758113263799, 0.957262638926831, 0, -7.12137956032554, -0.341310229615695, -0.398366286783207, 0, 4.36306773525701, 0.727757995598037, 0.0161524202463972, 0.00328949677611852, 0, 0.646073698871968, -0.552376741934983, 0.0423352347102997, 0.00685134741162386, 0.00142378713181378, 0, -2.20369291169022, 0.206374846769699, -0.00307468985755255, -0.00641976208887590, 0.000644268876651362, -0.000314468785662137, 0, 0.805085740994988, -2.87845392228227e-05, -0.0177052713874819, 0.00441730888033289, -0.000202983161694171, -1.85434507865840e-05, 2.74388312258045e-06, 0, 0.480276022237539, -0.0120209612204380, 0.0132362745264743, -0.00138809278600756, -0.000270632552765224, 4.37348016741610e-05, -4.03968762245026e-06, 5.84181552157763e-07, 0, -0.450501388803422, -0.00938485806297601, -0.00231914725480405, 0.000203226195250302, 7.14257072426776e-05, -3.51594165238721e-06, 6.06537339101174e-07, 2.26827429965467e-07, -4.20145827156144e-08 };
            double[] btm_amp = new double[55] { 0, 0, -0.710901870496413, 0, -0.722444912627412, -0.824052400474863, 0, 0.809817447239475, -0.0641190289504968, -0.0214499706640699, 0, -0.268601624271952, 0.268774129148869, -0.0164383677514096, -0.00965486083377577, 0, -0.480147176115071, 0.205079479016189, -0.0133512996671874, 0.00327791938583150, 0.00143879741147851, 0, 0.447746994997076, -0.115600043865941, -0.00864476649083406, 0.00223129888330613, -0.000428448830367915, 0.000184937443952386, 0, 0.152552080025958, -0.0822928296511098, -0.000149559519955829, 0.000233544365570767, -0.000101154493574138, 5.20949955521931e-06, 2.27757961105164e-05, 0, -0.381717959728205, 0.0377015568334093, 0.00473592540579181, -0.000391524208853610, 4.67234860438394e-05, -1.47203885773536e-05, 2.38282976498767e-06, 1.77929509858474e-07, 0, 0.155989481336536, -0.0114781285270996, -0.000130729303620589, -2.91094248505794e-05, -5.28863469894906e-05, 2.23959765704303e-06, 2.40332319699653e-07, -2.54291986470683e-07, -4.52512110379807e-09 };
            double alpha2 = 0.000603698407162263;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata = ata + (atm_amp[i - 1] * aP[i - 1] + btm_amp[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata * Math.Cos((doy + 1 - 28) / 365.25 * 2 * Math.PI);
            double Tm = Tm0 + alpha2 * hort;
            double temp = 0;
            double pres = 0;

            refGPT(doy, lat, lon, h, ref pres, ref temp, ref undu);
            return Tm + (70.2 + 0.72 * temp);





        }

        /// <summary>
        /// GWMT-G
        /// </summary>
        /// <param name="doy"></param>
        /// <param name="lat">度</param>
        /// <param name="lon">度</param>
        /// <param name="h">米</param>
        /// <returns></returns>
        public static double GetTm_NewGWMT(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { 278.878922126623, 2.15857854883996, 0.600616811563194, -23.8844291007038, 0.866631637732601, 0.0799236864157538, 1.27171710675545, 0.201655969894329, -0.00192013630454366, -0.0290762180918472, -4.14824945023806, 0.384723490584441, 0.0142765561015163, 0.000352130159689246, -0.00385576374289023, 1.10083703694342, -0.0900167304636875, 0.0465315917388030, 9.78352200878827e-05, 0.00205548888463177, -0.000274963209435004, 1.77486121499639, -0.0341537462307192, 0.0377251285399367, 0.00642302172721095, -1.38696994524364e-05, 2.25230362460548e-05, 2.30124228650360e-06, 0.593405730336390, 0.141111124367763, 0.0251735888662852, 0.00229115095301066, -0.000173398016093833, -1.95137451094344e-05, -2.01969139347124e-06, 5.55165959725280e-07, -2.48474111032062, -0.0710912066819334, 0.00477963687558169, 0.000432030420091624, -2.52362703410468e-05, -1.95724443240973e-05, 9.02576496465945e-08, 7.88607227952088e-07, -7.00341367913975e-08, -0.754566881506873, 0.0527513977012387, 0.00340384682799872, 0.000106141789480790, -9.19549873827587e-05, -5.33717968696261e-06, 1.19160381696383e-07, 1.27644447953613e-07, 3.62824309368242e-08, -2.18268609320530e-09 };
            double[] atm_amp = new double[55] { -1.55313670814392, -7.78647876880465, -0.0139310294071413, -3.09372981884140, 0.0940647878586368, 0.101419294844923, -1.38444629118568, 0.349384659122824, 0.160791584358618, -0.0107588238246913, 1.63342997435595, 0.391880973968750, 0.158126660586491, -0.00998589268615349, 0.00140588712453859, 1.41225646731920, 0.348584064263974, 0.0869612026065511, -0.00531657720033376, -3.92513015030706e-05, 0.000189765765883699, 1.28244367256039, 0.109246583021198, 0.0418118879547596, 0.00197196223532505, -0.000266905357570645, -3.65607311526375e-05, -1.81906355661751e-05, -2.95184458943661, -0.0585075289855204, -0.00639191748004467, 0.000226614104641622, -9.11169655783831e-05, 2.74235096065195e-05, -7.06847879377754e-06, -1.29519193247347e-06, -0.629039257153166, 0.0616965997603819, -0.00604258361661401, -0.000467753440130023, 7.55348364590964e-05, -1.15529985801085e-06, -3.63493971671697e-07, -1.33006205121249e-07, -3.55878396011772e-09, 1.69412921559836, 0.0185542833140447, -0.00490287414150821, -0.000283026412756379, 2.71857095321464e-05, -2.19116337047524e-06, -3.59682946215350e-07, -1.21707336914927e-07, -3.87387184336050e-09, 6.67302470554065e-10 };
            double[] btm_mean = new double[55] { 0, 0, 0.127194360259930, 0, 0.325725905959781, 0.183196760488193, 0, -0.373872635652931, 0.109993844363194, 0.0144056698753492, 0, 0.243772304048486, 0.0424130459802300, -0.000915770190832362, 0.000722626959988575, 0, -0.275057757685615, 0.0362778388001155, 0.000766286631256663, -0.00158999044339973, 0.000149665754771084, 0, 0.277831812012910, 0.0201191430564916, -0.00602929014672312, -0.000420805906859577, -6.47522471376264e-05, 7.75152857782265e-06, 0, 0.0612710880319702, 0.00288709020681292, -0.00216386214301391, -0.000194598996048468, 2.97658201852402e-05, -7.36628072260763e-07, -9.74594076326481e-07, 0, 0.0774041405919679, 0.000300244242193781, 0.000309347202603461, -0.000124535637730704, 1.29312613300638e-05, 1.89082921319745e-06, -1.35779491844284e-07, -1.19050971315396e-07, 0, -0.129772644131216, -0.00506023606579378, 0.000330967581709867, -1.95078353201081e-05, 3.81122509206166e-06, 3.51061924472305e-07, -1.27044126340644e-07, 1.51520004632672e-08, -3.14875336157974e-11 };
            double[] btm_amp = new double[55] { 0, 0, -0.524155512029515, 0, -0.632448437929717, -0.107556935969268, 0, -0.467390242808072, 0.0396139454702870, -0.00904732786628331, 0, -0.143451497564704, 0.0235459042488781, -0.0212034333674806, -0.00286675499194933, 0, 0.219905051492786, 0.0346996499753378, -0.0149369872628095, -0.000658170795457169, -5.98824610551626e-05, 0, 0.0585456919788607, 0.0420836039309554, -0.00583035918026659, -0.000100863274457951, 0.000106807453065914, -6.30317421260911e-06, 0, 0.154758286563733, -0.00363545597217051, -0.00270751192240395, -0.000231699479944941, 4.81199862974727e-05, 3.18818809701594e-07, -7.41796875441974e-07, 0, 0.0106070693723255, -0.00706243503172443, 0.000334632443779056, -0.000145627716440956, 3.87031516200613e-06, -8.72451248166121e-07, 8.60534516135189e-08, -3.70232267522453e-08, 0, 0.0237626636741643, -0.00306746414926239, -0.000137006048925178, 3.99118719336389e-06, 7.78117518439355e-06, -1.33333341440368e-06, -7.45181863791079e-08, -1.02567521640328e-08, 5.46961222673586e-10 };
            double alpha2 = -0.00529777864470759;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata = ata + (atm_amp[i - 1] * aP[i - 1] + btm_amp[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata * Math.Cos((doy + 1 - 28) / 365.25 * 2 * Math.PI);
            double Tm = Tm0 + alpha2 * hort;
            return Tm;

        }

        /// <summary>
        /// GWMT-3（初始相位28）
        /// </summary>
        /// <param name="doy"></param>
        /// <param name="lat">度</param>
        /// <param name="lon">度</param>
        /// <param name="h">米</param>
        /// <returns></returns>
        public static double GetTm_GWMT3(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { 278.913215919400, 2.14949940678052, 0.590833646979766, -23.7214849195814, 0.865644211293756, 0.0782178815726925, 1.34027025756916, 0.197306915288619, -0.00375450244070382, -0.0308232383921506, -3.97927424842622, 0.378800781084526, 0.0155034124931438, -0.000285819645964615, -0.00343579799396760, 1.11352995034536, -0.100210075628748, 0.0443284828788882, -0.000619921182156436, 0.00226761636619069, -0.000231092791973620, 1.58427000800243, -0.0244038438340737, 0.0371844138114302, 0.00653834932760160, 3.08467156191234e-05, 3.07291298908998e-05, 4.88542383720760e-06, 0.658563131106544, 0.129968753803345, 0.0249733788380455, 0.00243286879193496, -0.000131668111365275, -1.42058313316915e-05, -2.40094109604957e-06, 4.27192318638710e-07, -2.47061056477351, -0.0626500437345843, 0.00464021546608267, 0.000714641162224955, 5.36442897544795e-06, -1.91366195741041e-05, 4.65114521721250e-07, 6.69958529622247e-07, -6.42651655469270e-08, -0.662954494298568, 0.0507494655840265, 0.00304793275564909, 0.000200084484051492, -7.97858530701794e-05, -5.58218695349397e-06, 1.09252728079267e-07, 1.43124861061441e-07, 3.21535261785446e-08, -2.01659757014211e-09 };
            double[] atm_amp1 = new double[55] { -1.56543950328602, -7.77125353045616, -0.0304100210695919, -3.03455152379024, 0.0734003054409295, 0.110572737779629, -1.25502010786658, 0.358024514546912, 0.151223725448855, -0.0143956943498417, 1.72639409949156, 0.350923690493862, 0.156629315927279, -0.00990530901479456, 0.00137178736241870, 1.50800445742000, 0.360225422604287, 0.0879310502926470, -0.00513947533735130, 0.000127977462086835, 0.000138075043475814, 1.34534497677976, 0.0921187718740789, 0.0453789864553460, 0.00278346297123499, -0.000227246731514813, -3.74840326153876e-05, -2.15661827047752e-05, -2.84765146970681, -0.0480681393183452, -0.00693592670379018, 0.000374592638188643, -5.71344638491046e-05, 1.99781005104237e-05, -8.04828603327305e-06, -1.13205591356152e-06, -0.505188317735299, 0.0534141211405702, -0.00503213235083518, -0.000223527407149327, 5.98530677052862e-05, 1.27897581508951e-07, -6.67841144795202e-07, -8.52644604369997e-08, 2.94277866444191e-09, 1.69783409152507, 0.0229540167918950, -0.00617096161673037, -0.000311924007014617, 2.30637060820435e-05, -1.75084125951169e-06, -4.85805525570616e-07, -1.02276475267123e-07, -9.41188273003356e-10, 1.33718682094179e-09 };
            double[] atm_amp2 = new double[55] { 0.220694375143305, 0.199417154983865, -0.0876516479492396, 0.998154390212594, -0.0521248137249479, 0.0365577659474512, 0.473532028524885, -0.0806224169229551, 0.0344944601959914, -0.000863861179219270, 0.285565248760291, 0.00977545021979250, 0.0108110398866087, 0.000333419513784363, 4.80308808514115e-05, -0.225425247030573, -0.0818841628386710, 0.00810784043219412, 0.00170773593211173, -0.000569474127761976, -7.43807585269741e-05, 0.297791723484541, -0.00246153238934958, -0.00538536635417484, 0.00118011794451199, -0.000179711003699080, -2.62154598653943e-05, -3.94037128131254e-06, -0.0942867295768597, 0.0279913737999801, -0.000945994482809730, -0.000617832340868573, 3.35739646762571e-06, -2.30552539231647e-05, -5.72102081770002e-07, -1.14528154645922e-07, 0.172038429726240, 0.0711310772775246, -0.00200740223454906, -8.55059047780013e-05, -8.52188846868502e-06, -6.80957423564302e-06, 1.28499268194030e-07, -5.15090298248223e-08, 8.95260549424183e-09, 0.161109755446748, 0.0607234314463057, 0.000528240305016790, 4.29045762555707e-05, -7.16385234529601e-06, -2.56534738204621e-06, 5.67150508099118e-08, 3.72600065734626e-09, 1.84053746760263e-09, -3.59055436080184e-10 };
            double[] btm_mean = new double[55] { 0, 0, 0.0778913832906402, 0, 0.305766582571777, 0.181805401360495, 0, -0.392793908331460, 0.117498073340271, 0.0165900132223144, 0, 0.274714751955104, 0.0440561183023827, -0.00119832592643154, 0.00102858572947345, 0, -0.271286997369797, 0.0381858940696460, 0.000623436317917528, -0.00171954215640291, 0.000141976427262609, 0, 0.316289147921853, 0.0220623761858407, -0.00578447703133520, -0.000447346333061321, -6.79807956643042e-05, 8.56724403628808e-06, 0, 0.0606285613126281, 0.00248950702288158, -0.00234438495124548, -0.000200639124428283, 2.91793649646248e-05, -6.87867820659508e-07, -1.15672689169403e-06, 0, 0.104701005159600, 0.00268972424142009, 0.000218747177694479, -0.000111455095369708, 1.33594830080594e-05, 2.14407372098487e-06, -9.97252193654757e-08, -1.08821678503383e-07, 0, -0.133142374907692, -0.00414272742607390, 0.000262792827397952, -1.10729331643706e-05, 3.29273727263117e-06, 6.30670477671021e-07, -1.09999924594656e-07, 9.59996879947487e-09, -1.66906487653197e-10 };
            double[] btm_amp1 = new double[55] { 0, 0, -0.536825767487692, 0, -0.669934973733195, -0.0961354570082268, 0, -0.481648512930249, 0.0422887685299079, -0.0102179381519530, 0, -0.137874695017711, 0.0203591092652743, -0.0213231486932230, -0.00304774901190854, 0, 0.250325438904054, 0.0362438567024283, -0.0158787570442349, -0.000587125113114690, -7.39583670523370e-06, 0, 0.0715764476710608, 0.0345077931187044, -0.00599798354528516, -0.000150078470798468, 0.000115270529703104, -7.13074905084231e-06, 0, 0.180018097787261, 0.00205192516269424, -0.00277630240068089, -0.000235610755688937, 5.33676706875092e-05, -1.43951386393434e-07, -7.90132826702608e-07, 0, 0.0150709418378970, -0.00870674691550205, 0.000165098767403727, -0.000155454299736496, 6.53400994366534e-06, -6.34962376938269e-07, 4.10631480979349e-09, -3.48992766210683e-08, 0, 0.0301245822069846, -0.00157918415021729, -0.000257333993977652, 4.67825115945709e-06, 7.86599087934725e-06, -1.22236020778164e-06, -5.84698776339738e-08, -6.14596025837151e-09, 1.76975728305646e-10 };
            double[] btm_amp2 = new double[55] { 0, 0, -0.202884447897337, 0, -0.101116652750967, -0.00358961765542378, 0, 0.0446559403184132, 0.00460539730240004, -0.00578547158750088, 0, -0.00483346898889771, 0.00930460069949077, -0.00348003837195780, 0.00115547207639656, 0, 0.0300014874110985, 0.00117959339836618, -0.000357907093530467, 0.000474170277650905, 9.56322072894601e-05, 0, -0.0187447459468689, -0.00159536679122844, -0.00112300511909845, -8.42325719069867e-06, 3.36523749432916e-05, -6.19723444785001e-06, 0, -0.00462821115946833, -0.00582672105895841, 0.000298446525703528, -9.31186378238575e-05, 3.89264494697580e-06, -1.21084389793801e-06, 8.21709218301671e-08, 0, -0.0387275534877036, -0.00362612352949715, -0.000161138020124982, -4.53176091852811e-05, 3.04293397392438e-06, 7.11724901859481e-08, -1.68923446126194e-07, 3.54961906344254e-08, 0, 0.000900232301982170, -0.000666684891949615, -0.000165671582451460, -3.15466002969626e-06, 1.03947813106344e-06, 1.24427199537653e-07, -3.45583374140451e-08, 3.44560644156420e-09, 1.82865959161095e-10 };
            double alpha2 = -0.00506962251180327;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata1 = 0; double ata2 = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata1 = ata1 + (atm_amp1[i - 1] * aP[i - 1] + btm_amp1[i - 1] * bP[i - 1]);
                ata2 = ata2 + (atm_amp2[i - 1] * aP[i - 1] + btm_amp2[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata1 * Math.Cos((doy + 1 - 28) / 365.25 * 2 * Math.PI) + ata2 * Math.Cos((doy + 1 - 28) / 365.25 * 4 * Math.PI);
            double Tm = Tm0 + alpha2 * hort;
            return Tm;

        }

        /// <summary>
        /// GWMT-3误差建模(初始相位估计)，初始值 GWMT3
        /// </summary>
        /// <param name="doy"></param>
        /// <param name="lat">度</param>
        /// <param name="lon">度</param>
        /// <param name="h">米</param>
        /// <returns></returns>
        public static double GetTm_dGWMT33(double doy, double lat, double lon, double h)
        {
            double STm = GetTm_GWMT_G(doy, lat, lon, h);
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { -2.64181134797048e-05, 7.37781237585634e-06, -4.13239579170100e-05, 0.000120666581043613, -5.34249559969313e-06, 1.72945758700018e-05, -0.000160626710133375, 1.99886780428974e-05, 1.12287252972134e-05, -1.20660758820537e-06, 0.000239264097907303, 1.76572625993075e-05, 3.78362735795149e-06, -8.70799968170004e-07, -4.85221551369830e-07, -9.54125890060798e-05, 6.99635661276114e-06, 8.30920702321665e-07, -3.29049725814379e-07, -3.58768603861775e-08, -3.21345054847245e-09, 0.000127996673474143, 1.99661523131668e-06, 9.77772242049822e-07, -4.36145062377339e-07, -4.24345325842841e-08, -1.62710761479378e-09, -1.12645625580661e-09, -1.62945071844051e-05, -5.82985530561340e-06, 4.35609478966176e-08, 3.21326904460867e-08, -1.44509742209491e-08, 2.90781135306415e-09, -5.49187519864671e-10, -5.94796158779466e-11, 4.43891414582366e-05, 4.97466748795190e-06, -7.79549392420236e-07, -8.89655401664010e-08, 6.67823943461515e-09, 7.42296810037302e-10, -1.31602967715693e-10, -2.08469949854023e-11, -7.91889389714107e-12, -0.000105856481835542, 2.60077552104668e-06, -3.67821694729984e-07, -1.17566055222473e-07, 6.84418981042910e-09, 4.08288931444869e-10, -9.48544116953507e-11, -5.67073048690645e-12, -1.39601001959700e-12, -5.56150312463810e-14 };
            double[] atm_amp1 = new double[55] { -0.100818432521713, 0.0858984887235352, -0.111167941706498, -0.0244059994101499, -0.0162940135440060, 0.0580129314615168, -0.405534704542458, 0.0168162582983349, 0.0371395809155193, -0.00504354020303506, 0.0581997087796655, 0.0424050796806276, 0.0171692146422237, -0.00123991897751011, -0.00201565159864626, -0.306161333278651, 0.0453411508491880, 0.00901430779349707, -0.00111204646731310, -5.18884998420590e-05, -3.89958027569772e-05, 0.288755261456557, 0.0428147863202663, 0.000498400793312923, -0.000578158942933702, -0.000110939990916619, 2.61585516741524e-06, -1.10172539357085e-06, 0.165235950753529, 0.00575491840678326, -0.00170407273567142, -0.000508169906656865, -2.93023742035658e-05, 4.52579450055004e-06, -4.73583333059030e-07, -3.11193440041526e-07, 0.0598076164677598, -0.00121583907060302, -0.00293484834273439, -0.000127619922047641, 5.45480930271917e-05, 2.57107329546351e-07, -3.56350655105931e-07, -1.27198779531729e-08, -1.53394177859596e-08, -0.217597280771104, -0.00954205156883979, -0.00134730630897185, -0.000157876652243446, 3.33563531527050e-05, 8.34007339655379e-07, -2.33371190679708e-07, -1.59363599213474e-08, -8.45619023837163e-10, -1.81961887420024e-10 };
            double[] atm_amp2 = new double[55] { 0.201093106675069, -0.171422627509996, 0.221704374532019, 0.0491817301836253, 0.0325052559240193, -0.115711192787741, 0.808813813084828, -0.0334916308146811, -0.0740788457965176, 0.0100612190282389, -0.115231556102638, -0.0845675929409563, -0.0342536849784805, 0.00247074752661556, 0.00402085964096150, 0.610740717176901, -0.0904604954336982, -0.0179883810219428, 0.00221830453410866, 0.000103311169828553, 7.78556131388621e-05, -0.575876341899345, -0.0854367648242859, -0.000991081775641697, 0.00115198006738494, 0.000221248940749493, -5.22614920704103e-06, 2.19493545259991e-06, -0.329817076806812, -0.0115126094124625, 0.00339979640374983, 0.00101455573855185, 5.84116149315865e-05, -9.02275882104421e-06, 9.43221979487586e-07, 6.20876999219871e-07, -0.119260403430974, 0.00244121461006140, 0.00585415319803521, 0.000254388894540865, -0.000108849318531799, -5.11041364932361e-07, 7.10693989711371e-07, 2.52853870555139e-08, 3.05772006893046e-08, 0.433906727346172, 0.0190537055213531, 0.00268789800159910, 0.000314552122267028, -6.65454787898073e-05, -1.66330645485340e-06, 4.65517610525948e-07, 3.17892410235870e-08, 1.68154047193830e-09, 3.62588821803402e-10 };
            double[] atm_amp3 = new double[55] { -0.0115096148166440, -0.0632544740986143, -0.0478124851565462, 0.428044267376402, 0.00144091898304310, 0.00870248148446170, -0.111897575387844, 0.0502879946011213, 0.00342393873625112, 0.000510406422267079, 0.738639847890781, 0.0209910778754952, -0.00389873543906017, -0.00218374039082286, 0.000208762095109088, 0.0126305953377329, -0.0170505706068122, -0.00601372662665587, 5.37528149549633e-05, -0.000178982913027204, 5.10200324024666e-05, 0.101719988190499, -0.0303229984430770, 0.00246945498665760, -0.00102506984452921, -3.28147024058619e-05, -3.23511705323898e-06, -2.76378991215525e-06, -0.194976605960669, -0.0272836091704530, 0.000876248393672501, 0.000652482427984150, -3.76858499887665e-05, 5.14864621037270e-06, -1.11832100013098e-06, 2.55847429927469e-08, 0.0451216166701954, 0.0145633605299934, 0.000247577061842409, -0.000131168025889717, -2.83203068154833e-05, 2.21342786128944e-06, -1.15999627359169e-07, -5.70019277274931e-08, -1.03146955177054e-08, -0.110003765755874, 0.0155357332751496, 1.99253846913847e-05, -0.000259974876476010, -5.02215537200452e-06, 5.60629107411252e-07, -2.02032686587448e-08, 3.62616018040951e-09, -4.39429419398946e-09, -2.64563200372730e-10 };
            double[] atm_amp4 = new double[55] { 0.00855243961701980, 0.0472855112607901, 0.0356779783386036, -0.319765884055430, -0.00108760806168685, -0.00647731295840578, 0.0834136648748915, -0.0375565632571853, -0.00254165251989813, -0.000383413085246196, -0.551742148212728, -0.0156625142776027, 0.00292004974962094, 0.00163062876870956, -0.000156838519824285, -0.00956270163494451, 0.0127527604214118, 0.00449590182109908, -4.06601558125405e-05, 0.000133673474453728, -3.81333385836991e-05, -0.0758516485019589, 0.0226672217180698, -0.00184456911394848, 0.000765503164587412, 2.44464599626560e-05, 2.41792792754416e-06, 2.06340720544545e-06, 0.145716348012477, 0.0203856840516212, -0.000655259497247505, -0.000487685894944269, 2.81357301090044e-05, -3.84556368076553e-06, 8.35060766784305e-07, -1.91887611786171e-08, -0.0336851707265910, -0.0108750268919543, -0.000185963907396230, 9.79142349309743e-05, 2.11848126451765e-05, -1.65315524201387e-06, 8.65412660632491e-08, 4.25830139648411e-08, 7.69896450075889e-09, 0.0820829750497430, -0.0116107270801029, -1.55349590002081e-05, 0.000194150434947732, 3.76368880274573e-06, -4.18768000848898e-07, 1.50074577507258e-08, -2.72636326135057e-09, 3.28377466119428e-09, 1.97342598732156e-10 };
            double[] btm_mean = new double[55] { 0, 0, -3.46399115855824e-05, 0, -5.14076455309490e-05, -5.60251025260367e-06, 0, -5.30822996448337e-06, 2.67969731838104e-07, 3.57568614668856e-07, 0, -2.42407779658440e-06, 6.41138511648277e-07, 3.48616937281118e-07, 1.32985803683756e-07, 0, 1.94441366002461e-05, 6.39762080573064e-07, -2.12350478118488e-09, -1.56638992604878e-08, 4.10948193916527e-08, 0, -1.19140349792577e-05, 1.06228443048533e-06, 1.65793796004018e-08, -1.08418595322893e-08, 8.86531038388714e-09, 6.98163667440622e-10, 0, 1.92095752317929e-05, 1.51518565816242e-06, -5.13552875632347e-08, 1.95591536979267e-08, 7.65826354635268e-09, -2.44138069816301e-11, -1.50297079908980e-10, 0, -1.14655779658759e-05, -2.10424380872421e-07, 1.40460778402546e-07, 3.90811343771289e-09, 1.13147632573257e-09, -1.57899774712441e-10, -1.60647521984871e-11, -1.33495667576197e-12, 0, 2.15500851102244e-06, 1.16253364376062e-07, 7.34616373331766e-08, 5.31033156141136e-09, 7.46596499576047e-10, -9.15903685594827e-11, -1.34696402329455e-11, 1.08199547034055e-12, 1.42951346087345e-13 };
            double[] btm_amp1 = new double[55] { 0, 0, -0.112521590684270, 0, -0.158052631412358, -0.0346842431507601, 0, -0.0661981194537515, 0.00510878128231789, 0.000370010572779452, 0, 0.0179134778149374, -0.00304579977831727, -0.00154367102840513, 0.000728656971349517, 0, 0.0102665663925900, 0.00183972438615969, 0.000237027768993779, -0.000124589335836438, 8.14227917334561e-05, 0, -0.00585544774333003, 0.00112641344102122, 0.000188752480037271, -8.11557779042778e-05, 1.87260233867874e-05, 4.92141484306745e-07, 0, 0.0547017569918645, 0.00581507221288457, -0.000514782085180602, 1.23357888457199e-05, 1.52586873322436e-05, -1.79467650716539e-06, -5.23729716925427e-07, 0, 0.00929990291910346, 0.000249282467554521, 0.000252774735629087, -1.75888113582519e-05, 4.21957628967335e-06, -2.43407595979897e-07, -1.54688245420485e-08, -1.54225853412363e-08, 0, 0.0178047853139854, 0.00191794477016384, 0.000192050619520079, 9.81921685439784e-06, 1.68937450633648e-06, -1.69711527686970e-07, -4.76933028322674e-08, 5.40251369984274e-09, 2.73328981210517e-10 };
            double[] btm_amp2 = new double[55] { 0, 0, 0.224434983940125, 0, 0.315247544782478, 0.0692016891746251, 0, 0.132113211157162, -0.0101980515811084, -0.000737921324135686, 0, -0.0357612893271430, 0.00608078701029391, 0.00308292474136680, -0.00145398742532245, 0, -0.0204185248476726, -0.00366784282447751, -0.000472826110931123, 0.000248698226526757, -0.000162343229717028, 0, 0.0116445023139330, -0.00224429975480354, -0.000376647593951700, 0.000161965924501320, -3.73455197416932e-05, -9.78669784687253e-07, 0, -0.109102834293392, -0.0116007101375106, 0.00102723539714126, -2.45528953750800e-05, -3.04310138933075e-05, 3.58170955449164e-06, 1.04480578393525e-06, 0, -0.0185992873651563, -0.000497827394702325, -0.000504007029449642, 3.51207112162117e-05, -8.41656615344272e-06, 4.85130528264869e-07, 3.08034044876740e-08, 3.07687831654805e-08, 0, -0.0355325401085667, -0.00382747864412983, -0.000383013506051865, -1.95749142012238e-05, -3.36889941146673e-06, 3.38383864128428e-07, 9.51317233250936e-08, -1.07775048383203e-08, -5.44439318372474e-10 };
            double[] btm_amp3 = new double[55] { 0, 0, -0.0103816071445374, 0, -0.0273118038186452, 0.0157140436519350, 0, 0.0457207373415732, -0.00489880235528034, 9.24156683865809e-05, 0, -0.0212687292060425, 0.00508034660391298, 0.00284502887364265, -0.000355983469294793, 0, 0.0527699292837614, 0.000614745851740350, -3.89219918578873e-05, 0.000155798537957906, 5.41132085676216e-05, 0, -0.0321975097975859, 0.00228646844339197, -8.77021252094701e-05, 8.26394942098285e-05, 1.12186290882078e-05, 8.46434470482383e-07, 0, 0.0114722190147399, -0.000801283478585212, 0.000317911673994827, 4.39745931127475e-05, 6.35268156469496e-06, 1.33782580044522e-06, 1.12035143801873e-08, 0, -0.0422687222672107, -0.000533980368481693, 0.000129980840369159, 2.77297774307918e-05, -1.29101314007367e-06, -4.06036303204661e-07, -4.76400457943542e-08, 1.30673626893507e-08, 0, -0.0128131865779221, -0.00124475829860156, 4.96318425341223e-05, 7.50408038081959e-06, 7.81247941811779e-07, -1.67838095976376e-07, -3.31324278442979e-09, -1.01009361810315e-09, 4.46246215189867e-10 };
            double[] btm_amp4 = new double[55] { 0, 0, 0.00770322489997670, 0, 0.0203330396000749, -0.0117541131725768, 0, -0.0341815678302182, 0.00366081092980088, -6.89700249453813e-05, 0, 0.0158969719487756, -0.00379636834160951, -0.00212590267221116, 0.000266214748088595, 0, -0.0394183075371400, -0.000458797317794909, 2.92647110590270e-05, -0.000116430609698258, -4.04043305639898e-05, 0, 0.0240476435294536, -0.00170684621483160, 6.55775836815444e-05, -6.17651710522133e-05, -8.36957594419961e-06, -6.31018055486564e-07, 0, -0.00854338997141298, 0.000601597702208647, -0.000237708024126920, -3.28463616260723e-05, -4.73655483795506e-06, -1.00004226262212e-06, -8.59335500039784e-09, 0, 0.0315780543779588, 0.000398753188275945, -9.69749062490599e-05, -2.07210357718672e-05, 9.66436259112093e-07, 3.03209675764615e-07, 3.55856562140001e-08, -9.76646451363351e-09, 0, 0.00957952576974275, 0.000930459226663715, -3.69999807786961e-05, -5.60029885320605e-06, -5.82928931093235e-07, 1.25248839908587e-07, 2.45460430091558e-09, 7.55553298485589e-10, -3.33289689681637e-10 };

            double alpha2 = -1.79288876610905e-08;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata1 = 0; double ata2 = 0; double ata3 = 0; double ata4 = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata1 = ata1 + (atm_amp1[i - 1] * aP[i - 1] + btm_amp1[i - 1] * bP[i - 1]);
                ata2 = ata2 + (atm_amp2[i - 1] * aP[i - 1] + btm_amp2[i - 1] * bP[i - 1]);
                ata3 = ata3 + (atm_amp3[i - 1] * aP[i - 1] + btm_amp3[i - 1] * bP[i - 1]);
                ata4 = ata4 + (atm_amp4[i - 1] * aP[i - 1] + btm_amp4[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata1 * Math.Cos((doy) / 365.25 * 2 * Math.PI) + ata2 * Math.Sin((doy) / 365.25 * 2 * Math.PI) + ata3 * Math.Cos((doy) / 365.25 * 4 * Math.PI) + ata4 * Math.Sin((doy) / 365.25 * 4 * Math.PI);
            double Tm = Tm0 + alpha2 * hort + STm;
            return Tm;

        }

        /// <summary>
        /// GWMT-3误差建模(初始相位估计)，初始值 GWMT-G
        /// </summary>
        /// <param name="doy"></param>
        /// <param name="lat">度</param>
        /// <param name="lon">度</param>
        /// <param name="h">米</param>
        /// <returns></returns>
        public static double GetTm_dGWMTG3(double doy, double lat, double lon, double h)
        {
            double STm = GetTm_GWMT_G(doy, lat, lon, h);
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { 4.36493029821178e-06, 4.18872728093369e-05, -6.45723486707995e-05, 0.000292561510415019, -1.40046709453467e-05, 2.65834568191789e-05, -6.10783167993066e-05, 5.54351649202942e-06, 1.84993754149533e-05, -1.67831563197951e-06, 0.000279984820007025, 1.91716587383168e-05, 6.61890483924349e-06, -9.58015147622678e-07, -5.36863452282582e-07, -0.000116545972883192, -6.57985589926783e-06, 2.34826943889132e-06, -2.98097150623234e-09, -1.78430635685976e-07, -1.34970180320414e-08, 0.000164545981312199, 3.22037462802364e-06, -3.84471612387205e-07, -2.80397510184742e-07, -7.55041691056284e-08, -5.82773835355989e-09, -1.68436241782161e-09, -2.08364282978873e-05, -1.46841908671043e-06, -5.35835555422438e-07, -7.17076546161227e-08, -1.70500683681235e-08, -1.12324953620420e-09, -6.52091758861369e-10, -7.97310940907862e-11, 6.31512412520941e-05, 1.66351278026554e-05, -1.26125451499999e-06, -9.12995784623822e-08, 7.39898453280748e-09, -1.19703769630333e-10, -7.23257364585664e-11, -3.90870858775808e-11, -4.01208431678791e-12, -6.44387096652045e-05, 1.13262596445275e-05, -3.08334799064586e-07, -1.12690209031077e-07, 7.46245434764184e-09, -5.18268041007021e-11, -6.61981779830285e-11, -6.85287303519776e-12, -1.48912945331270e-12, -1.58856343747331e-14 };
            double[] atm_amp1 = new double[55] { -0.100818432521713, 0.0858984887235352, -0.111167941706498, -0.0244059994101499, -0.0162940135440060, 0.0580129314615168, -0.405534704542458, 0.0168162582983349, 0.0371395809155193, -0.00504354020303506, 0.0581997087796655, 0.0424050796806276, 0.0171692146422237, -0.00123991897751011, -0.00201565159864626, -0.306161333278651, 0.0453411508491880, 0.00901430779349707, -0.00111204646731310, -5.18884998420590e-05, -3.89958027569772e-05, 0.288755261456557, 0.0428147863202663, 0.000498400793312923, -0.000578158942933702, -0.000110939990916619, 2.61585516741524e-06, -1.10172539357085e-06, 0.165235950753529, 0.00575491840678326, -0.00170407273567142, -0.000508169906656865, -2.93023742035658e-05, 4.52579450055004e-06, -4.73583333059030e-07, -3.11193440041526e-07, 0.0598076164677598, -0.00121583907060302, -0.00293484834273439, -0.000127619922047641, 5.45480930271917e-05, 2.57107329546351e-07, -3.56350655105931e-07, -1.27198779531729e-08, -1.53394177859596e-08, -0.217597280771104, -0.00954205156883979, -0.00134730630897185, -0.000157876652243446, 3.33563531527050e-05, 8.34007339655379e-07, -2.33371190679708e-07, -1.59363599213474e-08, -8.45619023837163e-10, -1.81961887420024e-10 };
            double[] atm_amp2 = new double[55] { 0.201122838078194, -0.171393552089563, 0.221687763975390, 0.0493257602383038, 0.0324985407055335, -0.115706350438427, 0.808879866090233, -0.0335001746839229, -0.0740744963487009, 0.0100613323501518, -0.115193334584795, -0.0845665234161989, -0.0342519780363127, 0.00247084662887732, 0.00402090332805143, 0.610710838883634, -0.0904741028500931, -0.0179872708375746, 0.00221850885686846, 0.000103221883023115, 7.78453782586223e-05, -0.575838992000605, -0.0854368543170755, -0.000991939602786229, 0.00115217872173405, 0.000221223794217343, -5.22871292565840e-06, 2.19418758092536e-06, -0.329832499950507, -0.0115083751051642, 0.00339985665582556, 0.00101445609120198, 5.84104565685728e-05, -9.02636957601336e-06, 9.43129132824325e-07, 6.20807159508080e-07, -0.119238546800376, 0.00245110292779274, 0.00585398282487453, 0.000254375083714275, -0.000108848620570259, -5.11762957984217e-07, 7.10727241106649e-07, 2.52850860919315e-08, 3.05799430192281e-08, 0.433935440565105, 0.0190623467844620, 0.00268789639315621, 0.000314582728973324, -6.65460589171371e-05, -1.66369101204171e-06, 4.65530039569174e-07, 3.17906670124844e-08, 1.68180695880915e-09, 3.62396182658838e-10 };
            double[] atm_amp3 = new double[55] { 0.120618328410865, 0.0561351860050735, -0.100295699488795, 1.02563186198886, -0.0297643936913001, 0.0305897158216788, 0.171600911566273, 0.00202127748028278, 0.0240754302775489, -7.02023660217131e-06, 0.909605558125585, 0.0268445485534909, 0.00257394353542393, -0.00198410600273534, 0.000237531716659647, -0.122334026399443, -0.0660722064528207, -0.00115952150663187, 0.00107622797156799, -0.000519912455977790, 6.48370803226011e-06, 0.280008089527158, -0.0317960739675716, -0.000754636392183646, -0.000318558516600793, -0.000140403503367054, -1.89305635125878e-05, -5.12236463953711e-06, -0.251420162379539, -0.0105259563957285, 0.000309906307749807, 0.000282603563334020, -3.56728550915697e-05, -8.65380735040599e-06, -1.46071482191860e-06, -4.30004700937046e-08, 0.148123486834639, 0.0571475610895196, -0.000954303243585643, -0.000182340580606886, -3.34241802748995e-05, -1.86374946819814e-06, -3.90923779363778e-08, -8.78599501897616e-08, -4.95493200481516e-09, -0.0135452164984582, 0.0518907159974371, 0.000336287060306984, -0.000234294523261851, -9.31068896833389e-06, -9.74764459567131e-07, 1.37500382392878e-08, 5.86467044255230e-09, -3.29325170500361e-09, -4.79415252299433e-10 };
            double[] atm_amp4 = new double[55] { 0.185324687390951, 0.207015251766608, -0.0345385435687568, 0.479738792468359, -0.0428369771892147, 0.0228053695157286, 0.462702545909119, -0.102131913066190, 0.0250876928077609, -0.00107568242056944, -0.323009345858495, -0.00783119542235116, 0.0115797355736770, 0.00189771798988314, -0.000118344323545455, -0.190130384279890, -0.0528326593481489, 0.0109902838631870, 0.00132729677122805, -0.000322451077351195, -9.77181138022400e-05, 0.162677894514233, 0.0206964259129216, -0.00615802953819004, 0.00171073673100912, -0.000119495084125963, -1.85807766149476e-05, -1.09212271868198e-06, 0.0702007925954660, 0.0428054929532906, -0.00141296074360465, -0.000982541319591967, 3.08287271882844e-05, -2.23116837186831e-05, 3.76971139027164e-07, -1.10950343465893e-07, 0.104119992930063, 0.0460978395853346, -0.00179394937982934, 2.94505835709488e-05, 1.43566185996652e-05, -7.10795719415029e-06, 1.89434093676127e-07, 1.29823871443760e-09, 1.48697220719943e-08, 0.211132711944367, 0.0370281666146991, 0.000407721257005328, 0.000228507688175811, -1.97390589580925e-06, -2.47295987618250e-06, 6.04335164589110e-08, 2.68434301370331e-10, 4.75682686489198e-09, -9.01047697448403e-11 };
            double[] btm_mean = new double[55] { 0, 0, -7.37963510971345e-05, 0, -7.39115271490147e-05, -6.26547385371022e-06, 0, 1.88492135188527e-06, 1.03868398038890e-06, -1.19615507572017e-06, 0, -1.42933680439067e-06, 1.98773743434416e-06, -1.73313515011545e-07, 2.65658347220524e-07, 0, 2.41474515521133e-05, 9.84753355077039e-07, -1.04795835304606e-08, 1.12051377083935e-07, 5.48512074659827e-08, 0, -1.30389755546441e-05, 6.20101543964330e-07, -1.64161438426215e-07, -1.76333872113933e-09, 1.35084030089272e-08, -1.14464668288647e-09, 0, 1.83320367808106e-05, 4.48298929487103e-07, -1.31829487730281e-08, 9.87313714454947e-10, 7.39374572608850e-09, -2.59668071065165e-10, -1.60097536404021e-10, 0, -1.65219545616006e-05, -6.02596720204753e-07, 7.73352170335918e-08, -6.31064632999146e-09, 1.54906928504739e-09, -1.66769717827939e-10, -5.33775612194678e-11, 8.30503887458016e-12, 0, 6.50798787213226e-07, 1.24506993294763e-07, 3.42833523040284e-08, 4.79256463426349e-09, 9.66105637495707e-10, -6.59789919970059e-11, -2.02941140560300e-11, 2.25023363636298e-12, 1.03648494456731e-13 };
            double[] btm_amp1 = new double[55] { 0, 0, -0.112576576031048, 0, -0.158081221629625, -0.0346850697344453, 0, -0.0661889705731760, 0.00511078031417118, 0.000368111781341211, 0, 0.0179132445189043, -0.00304278820423200, -0.00154482675080450, 0.000729103461540193, 0, 0.0102755345961422, 0.00183974414637912, 0.000236836928220964, -0.000124443371664544, 8.14531050253989e-05, 0, -0.00586285119527018, 0.00112575480615525, 0.000188464235931964, -8.11543845875879e-05, 1.87368887898041e-05, 4.89471871358949e-07, 0, 0.0546998019173563, 0.00581354676246435, -0.000514702174021009, 1.23148578472937e-05, 1.52609121865097e-05, -1.79524128459898e-06, -5.23787980146690e-07, 0, 0.00928812579303323, 0.000248070529547413, 0.000252707223979157, -1.76022736109846e-05, 4.21979118771773e-06, -2.43448190992653e-07, -1.55387416429515e-08, -1.54161251049213e-08, 0, 0.0178057455369234, 0.00191784648347841, 0.000192001839997400, 9.81652959267042e-06, 1.68972441133836e-06, -1.69678229456204e-07, -4.76986001394957e-08, 5.40367485745546e-09, 2.73406303846280e-10 };
            double[] btm_amp2 = new double[55] { 0, 0, 0.224407395182347, 0, 0.315233238516939, 0.0692012836257409, 0, 0.132117815205052, -0.0101970495689801, -0.000738869791926813, 0, -0.0357614349532594, 0.00608229097952280, 0.00308234479159792, -0.00145376313750428, 0, -0.0204140552908702, -0.00366783912503400, -0.000472921492322112, 0.000248771348032837, -0.000162328182510523, 0, 0.0116408196780124, -0.00224462550903792, -0.000376792216987768, 0.000161966538132736, -3.73400432729024e-05, -9.80010971097548e-07, 0, -0.109103831022358, -0.0116014710361468, 0.00102727557108100, -2.45634220772421e-05, -3.04298946344276e-05, 3.58142633920781e-06, 1.04477696506671e-06, 0, -0.0186051884085857, -0.000498438021372596, -0.000504041297386780, 3.51139543953219e-05, -8.41646002990675e-06, 4.85109683778766e-07, 3.07683263037698e-08, 3.07720267891050e-08, 0, -0.0355320494442362, -0.00382752873061250, -0.000383037861259514, -1.95762630498862e-05, -3.36872247315243e-06, 3.38401188073831e-07, 9.51291130623951e-08, -1.07769152822972e-08, -5.44400805773673e-10 };
            double[] btm_amp3 = new double[55] { 0, 0, -0.131846089619600, 0, -0.0878490793758458, 0.0135643517233838, 0, 0.0724551698537028, -0.00214107831320277, -0.00337141285207889, 0, -0.0241637311340804, 0.0106512745299067, 0.000761543507524200, 0.000335738042865189, 0, 0.0707332416703635, 0.00132143931527688, -0.000253220268435710, 0.000439696007982847, 0.000111375451316758, 0, -0.0434188510418161, 0.00133104666420552, -0.000760036248369003, 7.75988840795845e-05, 3.13647508124622e-05, -2.86374643340580e-06, 0, 0.00870083343841772, -0.00429005797033759, 0.000496579017218495, -1.17805594972449e-05, 8.68240712465514e-06, 6.12939398414740e-07, 6.03927118235407e-08, 0, -0.0654544896377433, -0.00270482136246772, 3.34975300997863e-05, 5.98673231887799e-07, 5.30593463367502e-07, -3.63413690165492e-07, -1.48779593654651e-07, 3.43222090949291e-08, 0, -0.0122744375366548, -0.00164370239706926, -4.95522245617536e-05, 5.61544131007691e-06, 1.40362552591900e-06, -9.33292046014022e-08, -2.40058131202124e-08, 1.05361019643281e-09, 5.55535579930353e-10 };
            double[] btm_amp4 = new double[55] { 0, 0, -0.154802609098239, 0, -0.0606589334237939, -0.0146301344588520, 0, 0.00158613068905184, 0.00735033471982946, -0.00470317273833141, 0, 0.0120237098321751, 0.00365688939765500, -0.00491337266664129, 0.00119166140012246, 0, -0.0153854928723101, 0.000486661861370536, -0.000257441495123247, 0.000263392039374243, 3.62056901065756e-05, 0, 0.00903483085470280, -0.00298508100691079, -0.000833929915061719, -6.85091636426532e-05, 1.85837420858772e-05, -5.59482995219316e-06, 0, -0.0122512364097525, -0.00406597852226305, 1.32902232031691e-06, -0.000107440550825596, -1.61963348657125e-06, -1.96985888004089e-06, 5.72172194564547e-08, 0, 0.000558121284861667, -0.00250559550378103, -0.000226059844884398, -5.70194138350963e-05, 3.40353551560044e-06, 3.60232548675976e-07, -9.97277384892843e-08, 1.86701323391196e-08, 0, 0.0103003368154610, 0.000396714926790172, -0.000169696807548056, -8.12709075225055e-06, 2.49746204682942e-07, 2.24935024499553e-07, -2.52295944022575e-08, 3.51657636636824e-09, -1.87073509568877e-10 };

            double alpha2 = 1.33370727240335e-08;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata1 = 0; double ata2 = 0; double ata3 = 0; double ata4 = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata1 = ata1 + (atm_amp1[i - 1] * aP[i - 1] + btm_amp1[i - 1] * bP[i - 1]);
                ata2 = ata2 + (atm_amp2[i - 1] * aP[i - 1] + btm_amp2[i - 1] * bP[i - 1]);
                ata3 = ata3 + (atm_amp3[i - 1] * aP[i - 1] + btm_amp3[i - 1] * bP[i - 1]);
                ata4 = ata4 + (atm_amp4[i - 1] * aP[i - 1] + btm_amp4[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata1 * Math.Cos((doy) / 365.25 * 2 * Math.PI) + ata2 * Math.Sin((doy) / 365.25 * 2 * Math.PI) + ata3 * Math.Cos((doy) / 365.25 * 4 * Math.PI) + ata4 * Math.Sin((doy) / 365.25 * 4 * Math.PI);
            double Tm = Tm0 + alpha2 * hort + STm;
            return Tm;

        }

        /// <summary>
        /// GWMT-3(初始相位估计)
        /// </summary>
        /// <param name="doy"></param>
        /// <param name="lat">度</param>
        /// <param name="lon">度</param>
        /// <param name="h">米</param>
        /// <returns></returns>
        public static double GetTm_GWMT3_C(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { 278.913188096746, 2.14950742718754, 0.590789746716253, -23.7213627787237, 0.865639881843554, 0.0782363926363140, 1.34011243725620, 0.197325830341262, -0.00374338749027398, -0.0308245525724480, -3.97903875966283, 0.378818873268100, 0.0155068196528650, -0.000286763643923820, -0.00343631728885299, 1.11343491641740, -0.100201687558323, 0.0443293020976784, -0.000620208720209997, 0.00226756126675649, -0.000231089993804298, 1.58439212488870, -0.0244004819257466, 0.0371853697135693, 0.00653788757250158, 3.08096698298485e-05, 3.07283558116838e-05, 4.88417260842204e-06, 0.658551748837363, 0.129963133710665, 0.0249732954782314, 0.00243291795666402, -0.000131687055805363, -1.42030722253625e-05, -2.40143703723178e-06, 4.27102227192305e-07, -2.47057611362648, -0.0626461452352030, 0.00463942374907383, 0.000714564708605386, 5.37125643613954e-06, -1.91359549026202e-05, 4.64974099656508e-07, 6.69943581627749e-07, -6.42730823380616e-08, -0.663055706730110, 0.0507518721280534, 0.00304755440474792, 0.000199964069710422, -7.97784736209946e-05, -5.58180734610969e-06, 1.09176232360732e-07, 1.43122289515834e-07, 3.21522873062252e-08, -2.01673217485194e-09 };
            double[] atm_amp1 = new double[55] { -1.50041650720067, -6.86207633157657, -0.138359394772746, -2.73747994933249, 0.0493299487832529, 0.156871656298043, -1.52760047566881, 0.336914477590665, 0.172342250538743, -0.0179141726415766, 1.60170135152474, 0.356154075624453, 0.157205716715842, -0.0100958562628429, -0.000789145326253860, 1.04208302774603, 0.367403177234893, 0.0876300614858777, -0.00570704525320971, 6.25250307287467e-05, 8.44481117799898e-05, 1.49157570953432, 0.125173180828208, 0.0410699000474923, 0.00191047034912294, -0.000314108170385402, -3.08954039049185e-05, -2.03834047675852e-05, -2.38074470352395, -0.0372204842937187, -0.00790504267428056, -0.000173309705657180, -8.03858968448419e-05, 2.23878102072054e-05, -7.66918065774267e-06, -1.32335766192616e-06, -0.391856964702469, 0.0465400794001813, -0.00743370754009626, -0.000327455664798688, 0.000108062894521664, 3.71758963019377e-07, -9.53440456659485e-07, -8.89430366951757e-08, -1.27047369477537e-08, 1.30037740379113, 0.0109796245373164, -0.00686465615028773, -0.000436727891016108, 5.39774866326154e-05, -7.31222257620921e-07, -6.67720367929715e-07, -1.07376135528512e-07, -1.68704578671155e-09, 1.01359389323324e-09 };
            double[] atm_amp2 = new double[55] { -0.500137340862798, -3.65251581480723, 0.208080871066523, -1.31012990023140, 0.0653843131764986, -0.0661807104897235, 0.246633355642471, 0.126884847933411, -0.00633923490099416, 0.00361273893813057, 0.658097800741399, 0.0726277994383518, 0.0359077797540866, -0.00196627770131014, 0.00463536790062862, 1.28624169803194, 0.0708998946246274, 0.0213998948340472, -8.38935949970012e-05, 0.000160635033700468, 0.000139703776336620, 0.0267640707379851, -0.0441733501914384, 0.0193361604006705, 0.00239884036461613, 0.000119457054764780, -2.20160504089276e-05, -7.46563067441551e-06, -1.60541133498746, -0.0330442632993222, 0.000292969653795580, 0.00118232869034709, 3.28175711624924e-05, -7.34889555455040e-08, -2.66193655724543e-06, 1.13759099670023e-07, -0.345554647652344, 0.0263680211345037, 0.00360012048400759, 0.000154266462627596, -8.20371485412930e-05, -4.53597183404152e-07, 4.11538197669331e-07, -1.29042001713450e-08, 3.18972280463861e-08, 1.19444639439796, 0.0293355374194052, -7.64189594134694e-05, 0.000174841197730213, -5.62138224860149e-05, -2.44752349061516e-06, 2.47898877506969e-07, -1.40241694662405e-08, 1.25996653314160e-09, 9.61588722056570e-10 };
            double[] atm_amp3 = new double[55] { 0.120618516808835, 0.0561365366118022, -0.100293893336556, 1.02563160899580, -0.0297637247453766, 0.0305902400335862, 0.171599689548315, 0.00201940361476104, 0.0240755930742382, -6.81862634389620e-06, 0.909604820942210, 0.0268438734550684, 0.00257368475550532, -0.00198408161062316, 0.000237518801587056, -0.122332799780346, -0.0660718947173212, -0.00115946384073135, 0.00107616553684208, -0.000519919476667818, 6.49088617324576e-06, 0.280001867993523, -0.0317951953771445, -0.000754669536304504, -0.000318556639991300, -0.000140397607584852, -1.89301272168015e-05, -5.12252069237291e-06, -0.251422573741497, -0.0105264550496932, 0.000309864552521314, 0.000282617254712002, -3.56743580585621e-05, -8.65359809021540e-06, -1.46077295706346e-06, -4.30102647020022e-08, 0.148122046115171, 0.0571467403090303, -0.000954362741842064, -0.000182353209668102, -3.34248981707758e-05, -1.86348604978871e-06, -3.90899483498635e-08, -8.78435914485104e-08, -4.95512225365249e-09, -0.0135512499570729, 0.0518908705261625, 0.000336204578515056, -0.000234296379482631, -9.30984887072691e-06, -9.75054288754819e-07, 1.37426623952461e-08, 5.86196514899894e-09, -3.29314081838771e-09, -4.79425879764730e-10 };
            double[] atm_amp4 = new double[55] { 0.185324853528386, 0.207017162410605, -0.0345361197760357, 0.479738426725406, -0.0428359922266472, 0.0228060734285334, 0.462700849547531, -0.102134471975262, 0.0250879308508293, -0.00107540412435133, -0.323010427652613, -0.00783208394414203, 0.0115794068464928, 0.00189775096377236, -0.000118363252459037, -0.190128619051241, -0.0528322207216475, 0.0109903501350676, 0.00132721405656199, -0.000322460823060812, -9.77084085309927e-05, 0.162669464577411, 0.0206975584559388, -0.00615808366507243, 0.00171073923822895, -0.000119487326024650, -1.85802175533856e-05, -1.09232594463691e-06, 0.0701976968960437, 0.0428048565600630, -0.00141301689611246, -0.000982522577472081, 3.08267768853921e-05, -2.23114195463788e-05, 3.76896481463219e-07, -1.10962831738382e-07, 0.104117658575100, 0.0460967330456717, -0.00179402901354907, 2.94337650925985e-05, 1.43555530989341e-05, -7.10760177968512e-06, 1.89437033337390e-07, 1.32021690637882e-09, 1.48694459122703e-08, 0.211125177695541, 0.0370283474921144, 0.000407612397168171, 0.000228505033114190, -1.97275891829968e-06, -2.47334267302181e-06, 6.04234403289339e-08, 2.64874140942174e-10, 4.75699336504821e-09, -9.01212781705431e-11 };
            double[] btm_mean = new double[55] { 0, 0, 0.0778582359271009, 0, 0.305714461709820, 0.181800242713395, 0, -0.392798582642792, 0.117498505961115, 0.0165902611506168, 0, 0.274711940625892, 0.0440567349083808, -0.00119802207546578, 0.00102872202022874, 0, -0.271268919155829, 0.0381865217981856, 0.000623455329929924, -0.00171954071665888, 0.000142018255188890, 0, 0.316276312423373, 0.0220633095424312, -0.00578445256390206, -0.000447347879375764, -6.79718488057987e-05, 8.56761363032641e-06, 0, 0.0606486214595060, 0.00249090804404809, -0.00234443724097208, -0.000200622673498719, 2.91859913651147e-05, -6.87997261744472e-07, -1.15688947676238e-06, 0, 0.104690501092641, 0.00268959024699412, 0.000218861175031165, -0.000111452042994103, 1.33604954107576e-05, 2.14389239545478e-06, -9.97454896011204e-08, -1.08822592741694e-07, 0, -0.133139858029399, -0.00414256204740807, 0.000262864586982487, -1.10676197060391e-05, 3.29346830035555e-06, 6.30578147597733e-07, -1.10016436782012e-07, 9.60123453626269e-09, -1.66687069877557e-10 };
            double[] btm_amp1 = new double[55] { 0, 0, -0.592474363698756, 0, -0.757016835212181, -0.120633956407520, 0, -0.496825731085964, 0.0429181586421317, -0.00876547178416507, 0, -0.105353518559604, 0.0151567931320815, -0.0206080149036762, -0.00199618468976070, 0, 0.234073152332763, 0.0342434536161569, -0.0139595644631094, -0.000649511631483980, 7.48057018894800e-05, 0, 0.0581375116319007, 0.0319785094818971, -0.00517379912409762, -0.000215328549146059, 0.000121786844872138, -5.88400035439616e-06, 0, 0.215648828789102, 0.00764967427206188, -0.00299696664561113, -0.000198315684707735, 6.29730886705187e-05, -1.92346293134326e-06, -1.23018926349719e-06, 0, 0.0227738259919957, -0.00753510229454354, 0.000400357334933788, -0.000156575672922633, 1.00605993508382e-05, -8.11129045020365e-07, -1.17985330460352e-08, -4.66203770840149e-08, 0, 0.0447385789602677, 0.000506137624571496, -3.80305633465549e-05, 1.40005599404080e-05, 8.72202079275257e-06, -1.26259533124249e-06, -9.99686357525596e-08, -9.24977423909946e-11, 4.31450137073899e-10 };
            double[] btm_amp2 = new double[55] { 0, 0, -0.0160322365123282, 0, 0.0151529120779040, 0.0261389358077863, 0, -0.0836409846337869, 0.00874530364824789, -0.00531500399742182, 0, -0.0975208757599717, 0.0152007002241127, -0.00646874431503802, -0.00281919450797693, 0, 0.0917136492510105, 0.0125671602805795, -0.00758564128476682, -1.42998260357928e-05, -0.000165658670776260, 0, 0.0437064316796614, 0.0132133039527877, -0.00306340815195245, 9.47422143844603e-05, 1.42903116618262e-05, -4.17326870977054e-06, 0, -0.0284647049973524, -0.0106815314407082, -0.000216395437840857, -0.000130094091565333, -6.52500764143410e-06, 3.51718544227187e-06, 6.90853500422272e-07, 0, -0.0118485427725292, -0.00439798202414299, -0.000430064985736363, -3.45148514598163e-05, -5.49008534075100e-06, 2.00688537643076e-07, 3.26423063116136e-08, 1.51379780958896e-08, 0, -0.0220381001133682, -0.00453482636521039, -0.000498289496384260, -1.74799693189911e-05, 1.54617812100303e-07, -2.09175264739836e-07, 6.89406009362324e-08, -1.35306185177608e-08, -4.65216402832105e-10 };
            double[] btm_amp3 = new double[55] { 0, 0, -0.131845531249464, 0, -0.0878497173827726, 0.0135651357002715, 0, 0.0724552088394998, -0.00214117225473257, -0.00337124715432624, 0, -0.0241630348995450, 0.0106509127299897, 0.000761547317521530, 0.000335799681847582, 0, 0.0707331693216136, 0.00132114537859471, -0.000253238549730224, 0.000439676710889915, 0.000111375778475030, 0, -0.0434190945062815, 0.00133101546928283, -0.000760024908054825, 7.75953715138131e-05, 3.13647390886220e-05, -2.86428994071561e-06, 0, 0.00870024312544870, -0.00428991567026099, 0.000496588520117096, -1.17734342370299e-05, 8.68209904846186e-06, 6.12850115727258e-07, 6.03954239402411e-08, 0, -0.0654540569487844, -0.00270478875104890, 3.35043433363418e-05, 5.98040671335079e-07, 5.30680445023332e-07, -3.63427700400438e-07, -1.48775371261182e-07, 3.43177785154645e-08, 0, -0.0122742985624811, -0.00164378694806559, -4.95496234577225e-05, 5.61495227917866e-06, 1.40360789135346e-06, -9.33201342669980e-08, -2.40032892741270e-08, 1.05340138242539e-09, 5.55754971139686e-10 };
            double[] btm_amp4 = new double[55] { 0, 0, -0.154801705243619, 0, -0.0606597392796559, -0.0146290949050334, 0, 0.00158617416751691, 0.00735020310622798, -0.00470295476687029, 0, 0.0120246595408667, 0.00365642021852837, -0.00491336457376721, 0.00119174358132002, 0, -0.0153855491967448, 0.000486281898514954, -0.000257466655509226, 0.000263366087423822, 3.62061605860064e-05, 0, 0.00903444286455980, -0.00298512655708695, -0.000833915273905991, -6.85139121812310e-05, 1.85836907406423e-05, -5.59556641595334e-06, 0, -0.0122520028279973, -0.00406579346587519, 1.34137947143282e-06, -0.000107430970666329, -1.62003770289080e-06, -1.96997552920535e-06, 5.72198232166400e-08, 0, 0.000558710656689618, -0.00250554545142588, -0.000226050050067477, -5.70201942016128e-05, 3.40364444306072e-06, 3.60213404071138e-07, -9.97219541135940e-08, 1.86641778921115e-08, 0, 0.0103004911232927, 0.000396603433872343, -0.000169693799596728, -8.12774520596724e-06, 2.49723016932853e-07, 2.24946711751574e-07, -2.52263203719566e-08, 3.51630804937972e-09, -1.86777688444382e-10 };

            double alpha2 = -0.00506964012376460;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata1 = 0; double ata2 = 0; double ata3 = 0; double ata4 = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata1 = ata1 + (atm_amp1[i - 1] * aP[i - 1] + btm_amp1[i - 1] * bP[i - 1]);
                ata2 = ata2 + (atm_amp2[i - 1] * aP[i - 1] + btm_amp2[i - 1] * bP[i - 1]);
                ata3 = ata3 + (atm_amp3[i - 1] * aP[i - 1] + btm_amp3[i - 1] * bP[i - 1]);
                ata4 = ata4 + (atm_amp4[i - 1] * aP[i - 1] + btm_amp4[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata1 * Math.Cos((doy) / 365.25 * 2 * Math.PI) + ata2 * Math.Sin((doy) / 365.25 * 2 * Math.PI) + ata3 * Math.Cos((doy) / 365.25 * 4 * Math.PI) + ata4 * Math.Sin((doy) / 365.25 * 4 * Math.PI);
            double Tm = Tm0 + alpha2 * hort;
            return Tm;

        }

        /// <summary>
        /// GWMT-3(初始相位估计，考虑天变化)
        /// </summary>
        /// <param name="doy"></param>
        /// <param name="lat">度</param>
        /// <param name="lon">度</param>
        /// <param name="h">米</param>
        /// <returns></returns>
        public static double GetTm_GWMT3_C_D(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { 278.913188097120, 2.14950743203835, 0.590789720042615, -23.7213627729675, 0.865639902548481, 0.0782363927308371, 1.34011243531550, 0.197325826484017, -0.00374338738355388, -0.0308245520466987, -3.97903875730563, 0.378818877339062, 0.0155068205133418, -0.000286763890860013, -0.00343631725823704, 1.11343491015239, -0.100201690860026, 0.0443293022873576, -0.000620208658102620, 0.00226756123984507, -0.000231089998735478, 1.58439212360353, -0.0244004753637887, 0.0371853690903250, 0.00653788758591591, 3.08096590704719e-05, 3.07283541378535e-05, 4.88417273193241e-06, 0.658551743733080, 0.129963128694739, 0.0249732954770270, 0.00243291791905656, -0.000131687055671787, -1.42030714026868e-05, -2.40143675934510e-06, 4.27102336631301e-07, -2.47057610179647, -0.0626461425848206, 0.00463942369757520, 0.000714564693414340, 5.37125465908080e-06, -1.91359548073436e-05, 4.64974129002234e-07, 6.69943590224833e-07, -6.42730788836686e-08, -0.663055710321518, 0.0507518707649335, 0.00304755447037716, 0.000199964085915060, -7.97784721071275e-05, -5.58180766637502e-06, 1.09176210336729e-07, 1.43122290211307e-07, 3.21522865290533e-08, -2.01673232702633e-09 };
            double[] atm_amp1 = new double[55] { -1.50359389351680, -6.88539220090626, -0.137083414956074, -2.74581891273023, 0.0497961507652041, 0.156436781744063, -1.52599020754738, 0.337718889670002, 0.172296955381897, -0.0178892880305058, 1.60590922033741, 0.356611756250802, 0.157434614486986, -0.0101076395762882, -0.000758982585000300, 1.05035822477085, 0.367845073753737, 0.0877647923232471, -0.00570724647955695, 6.35382969348539e-05, 8.53672459556992e-05, 1.49167770671077, 0.124902997768231, 0.0411918943587793, 0.00192567180964808, -0.000313334280728821, -3.10417840388115e-05, -2.04298751130846e-05, -2.39105162790819, -0.0374356604909260, -0.00790309554079800, -0.000165806836224461, -8.01664860203305e-05, 2.23873891703414e-05, -7.68595400032295e-06, -1.32235241583523e-06, -0.394056610212945, 0.0467100172747354, -0.00741051421600200, -0.000326420986704923, 0.000107521617123011, 3.70022565236300e-07, -9.50788780617002e-07, -8.90319629661535e-08, -1.24917830067203e-08, 1.30803171224721, 0.0111643754597963, -0.00686501200384918, -0.000435553920383797, 5.36134667051492e-05, -7.47404605496918e-07, -6.66100663451935e-07, -1.07455659116843e-07, -1.67909060562311e-09, 1.01948145736122e-09 };
            double[] atm_amp2 = new double[55] { -0.490443092915572, -3.60816285126190, 0.208940276909841, -1.29240122329504, 0.0651764725821021, -0.0671919714309861, 0.256550989854838, 0.124736654638083, -0.00744972427308259, 0.00372968850089232, 0.647702817482626, 0.0703705713545525, 0.0348942999939424, -0.00190164431118696, 0.00464005548254637, 1.27942449645463, 0.0685230334953456, 0.0208336318596124, -4.69816591257502e-05, 0.000160270849444238, 0.000139111029983704, 0.0171054672800839, -0.0449765925560391, 0.0190704387042213, 0.00238656051791216, 0.000121471736930913, -2.18113832173575e-05, -7.33574049451827e-06, -1.58998366067295, -0.0328191320235705, 0.000342351495488140, 0.00118323369629953, 3.33351788572796e-05, -2.15632106740390e-07, -2.61230770397944e-06, 1.22257094816678e-07, -0.343001802806075, 0.0260803703841844, 0.00364735408491998, 0.000156107413452177, -8.27248245073960e-05, -4.57147728228947e-07, 4.17608193766559e-07, -1.22781207150326e-08, 3.19793739216335e-08, 1.18600525888166, 0.0292564420727342, -3.20220346835973e-05, 0.000177648413691716, -5.65628641643874e-05, -2.44248095974132e-06, 2.52083535728056e-07, -1.33324406972961e-08, 1.26859473536693e-09, 9.54852803555643e-10 };
            double[] atm_amp3 = new double[55] { 0.122999739955732, 0.0587934970674077, -0.100744802072331, 1.03168809037487, -0.0302876909315986, 0.0308833057556208, 0.177564244396706, 0.000691437489596723, 0.0243946612367816, -1.99785872107000e-05, 0.905317141266527, 0.0267526503120486, 0.00272292153791285, -0.00196071038227297, 0.000235831934108012, -0.124810830757577, -0.0667527261503340, -0.00101642828686318, 0.00109323585135110, -0.000524070936690564, 5.19126158635204e-06, 0.282085532581196, -0.0315209538663076, -0.000834567768081796, -0.000296180960171001, -0.000141947235079848, -1.91683337705855e-05, -5.13684067083098e-06, -0.250474634671335, -0.00998574216662525, 0.000291909246496190, 0.000269918772274343, -3.52754756345339e-05, -8.93832029569276e-06, -1.45499055653068e-06, -4.42924152090358e-08, 0.149476024972113, 0.0577416328026315, -0.000977327652658303, -0.000182035188699039, -3.32340073421311e-05, -1.95592884361174e-06, -3.64948792784629e-08, -8.77693964452551e-08, -4.75928449957812e-09, -0.0108373951815197, 0.0523617648755689, 0.000341742984358881, -0.000231292838925289, -9.33023315426893e-06, -1.00757684418208e-06, 1.44435338392427e-08, 5.85966613524236e-09, -3.23345930510065e-09, -4.80742762259579e-10 };
            double[] atm_amp4 = new double[55] { 0.183761741467557, 0.206274750668958, -0.0332189959428305, 0.466508922534718, -0.0424519990774646, 0.0223976076607926, 0.460472613070245, -0.102139663462668, 0.0247806840790088, -0.00107632175935673, -0.334713301354530, -0.00816915435026069, 0.0115475754204437, 0.00192297914032037, -0.000121798609127049, -0.188546030616976, -0.0519763982725866, 0.0110043850188291, 0.00131297750780608, -0.000315734285798994, -9.78124190718262e-05, 0.158970118976141, 0.0210951562883347, -0.00614933096375057, 0.00171447046536296, -0.000117657184395670, -1.83342357484406e-05, -1.02433050574879e-06, 0.0734322016299409, 0.0429313125044200, -0.00141837011199688, -0.000986108700356642, 3.12772657246579e-05, -2.21936613163248e-05, 3.95716056136771e-07, -1.10366905030294e-07, 0.102202103204556, 0.0453626398101101, -0.00178124793072085, 3.17982157222843e-05, 1.47855216308489e-05, -7.08133745124385e-06, 1.90093142636056e-07, 2.45961230137684e-09, 1.49196608554077e-08, 0.211274879890438, 0.0363550493327364, 0.000403700680597285, 0.000231556379543750, -1.85190424472124e-06, -2.45921096312441e-06, 6.02652083005793e-08, 1.77996395490908e-10, 4.79836084813624e-09, -8.35316426777732e-11 };
            double[] atm_amp5 = new double[55] { -0.0205617229457509, -0.0231485419903774, -0.0524563982463164, -0.0174700606215218, -0.0139312886359497, -0.00428446255857715, 0.0289417616270992, 0.0121393964234784, 0.00534112004061830, -0.00225727799185354, 0.0269351330714480, 0.0102973483325833, 0.00168671414654829, 0.00185694203356950, 0.000324620114105981, 0.00474575549207467, -0.00351645870331169, -0.00133623697070204, 0.000128365429388483, -3.64131943949197e-06, 6.02792147916078e-05, -0.0302546827731224, 0.000344790269017128, -0.000400360446164854, -0.000257087039585194, 1.52198201318880e-05, -2.65899286603112e-06, 4.12534640525621e-06, 0.0273684511832503, -0.00206738176270874, 0.000347053214784983, 2.16383055317555e-05, 1.35612995980041e-05, -3.25583149093547e-06, -5.99829699064995e-07, 2.55285432867403e-07, 0.0466895193483676, 0.00107937714295722, 0.000616209143039752, -2.26202866915416e-05, 9.20906913956784e-07, -7.11862904656690e-07, -4.91266804400284e-08, -7.56185887704408e-08, 7.43795898693108e-10, -0.0443928754454000, 4.64455852785867e-05, 1.20723616571776e-05, 5.48431384656341e-06, 2.28399258374416e-06, 5.98654236903030e-07, -5.47915083398008e-08, 1.79899033304983e-08, -1.35035335322408e-09, -4.15545717329992e-10 };
            double[] atm_amp6 = new double[55] { -0.0336801519300105, -0.0132874927409527, -0.292432001129928, 0.0444614171708192, -0.0211611485476957, -0.0180129456949471, 0.0227856583016144, 0.0150354131576962, -0.00443115949115174, 0.00143931501411051, -0.0262696869951009, -0.00896664793049747, 0.000925214619412443, -0.000629362342698296, 1.25070804350188e-05, -0.0184576429069697, -0.00603109638341317, -0.000136599431827293, 0.000363722259117332, 3.83843512437173e-05, 1.75277400470200e-05, 0.0166813885578653, 0.00790880799731665, 0.000254400382414843, 0.000333083773654716, -3.39186994970671e-05, -1.02786463168231e-05, 1.76209529278774e-06, 0.00766282407253595, -0.00775106332791737, 0.00101793054497267, -3.41950494345595e-06, -6.19461610731495e-06, -1.96938257323253e-06, -4.11768566599016e-08, 1.12048379370978e-07, -0.00733847005172744, 0.00399006673693712, -0.000414658491881626, -1.87725519454771e-05, 4.07109886538015e-06, 3.95370149191396e-07, -9.49701889355786e-08, -6.13528930812264e-09, 1.21410179053204e-08, -0.00721087626443461, 0.00227735849201357, 9.22822228237458e-05, 8.14297418448394e-06, -3.67025714801191e-06, -5.35815612992430e-07, 8.65023392931230e-08, -3.41053136045033e-09, -5.01692410982460e-09, 1.00507807741180e-10 };
            double[] btm_mean = new double[55] { 0, 0, 0.0778582718705853, 0, 0.305714476415429, 0.181800239555099, 0, -0.392798583933330, 0.117498505504886, 0.0165902608450345, 0, 0.274711939658912, 0.0440567344113229, -0.00119802230097914, 0.00102872187886491, 0, -0.271268923821498, 0.0381865215878222, 0.000623455354470002, -0.00171954070502172, 0.000142018254231164, 0, 0.316276320171668, 0.0220633097853836, -0.00578445253303862, -0.000447347872722017, -6.79718468611822e-05, 8.56761405949400e-06, 0, 0.0606486211597418, 0.00249090787714564, -0.00234443729512925, -0.000200622667186758, 2.91859909256101e-05, -6.87997556260304e-07, -1.15688947960933e-06, 0, 0.104690495378494, 0.00268958989540007, 0.000218861158288698, -0.000111452042297002, 1.33604955920894e-05, 2.14389240746673e-06, -9.97454903590295e-08, -1.08822592714690e-07, 0, -0.133139857979163, -0.00414256181683629, 0.000262864571525132, -1.10676203510254e-05, 3.29346821092389e-06, 6.30578190511812e-07, -1.10016435908046e-07, 9.60123516706882e-09, -1.66687335795543e-10 };
            double[] btm_amp1 = new double[55] { 0, 0, -0.592517826962367, 0, -0.756852538234236, -0.120471012915935, 0, -0.497346406006019, 0.0429731622959948, -0.00880166352826639, 0, -0.105989411947159, 0.0152542625167179, -0.0206498286309134, -0.00201473084085135, 0, 0.234648591772909, 0.0343236281787142, -0.0140081026707057, -0.000649484855923335, 7.37211564901966e-05, 0, 0.0584364637325225, 0.0320638413485914, -0.00519346644829413, -0.000214698511820207, 0.000121884398089535, -5.91161973878564e-06, 0, 0.215455696359060, 0.00758033986119054, -0.00299824087941529, -0.000199159187535078, 6.29304819201578e-05, -1.90095563059853e-06, -1.22584856321955e-06, 0, 0.0226844323534866, -0.00756392339089110, 0.000397596341060141, -0.000156791560413666, 1.00253645396150e-05, -8.09887568218689e-07, -1.16058022421319e-08, -4.65246476549127e-08, 0, 0.0445968172892046, 0.000476993962347011, -4.12768934787218e-05, 1.38867154043243e-05, 8.72310948583619e-06, -1.26389076582070e-06, -9.95271907834252e-08, -1.80893311278996e-10, 4.28256505130100e-10 };
            double[] btm_amp2 = new double[55] { 0, 0, -0.0122479856685579, 0, 0.0201765042638813, 0.0269100047817980, 0, -0.0803803898641259, 0.00846882091998009, -0.00525517731125233, 0, -0.0967410156603188, 0.0151041216752409, -0.00633576939309317, -0.00280633072886889, 0, 0.0902200674692880, 0.0123487649722207, -0.00749518093486767, -1.00592455618512e-05, -0.000166141261450248, 0, 0.0433210031113057, 0.0130063546683708, -0.00303008055221123, 9.61271494625296e-05, 1.35171380724485e-05, -4.13238473468550e-06, 0, -0.0298780663244048, -0.0107315294583263, -0.000197362578635673, -0.000128792407635824, -6.93538884869542e-06, 3.52999149471513e-06, 6.99074114448022e-07, 0, -0.0119903137251735, -0.00435138849078847, -0.000432694881401380, -3.34792953917844e-05, -5.55435846832665e-06, 2.06143714378024e-07, 3.27163402770885e-08, 1.54402008966990e-08, 0, -0.0223419072728562, -0.00453735096395125, -0.000497953074790828, -1.75672806810104e-05, 9.94859655807274e-08, -2.00940417160627e-07, 6.95790417038359e-08, -1.35303487715157e-08, -4.67938959495910e-10 };
            double[] btm_amp3 = new double[55] { 0, 0, -0.133741319117053, 0, -0.0886107845936190, 0.0133733656872964, 0, 0.0724603512133792, -0.00204741614867426, -0.00343028352780000, 0, -0.0239990865845136, 0.0106952193957979, 0.000697982395401740, 0.000351090948998333, 0, 0.0705176135374181, 0.00132624179604311, -0.000256421605349527, 0.000442951910695917, 0.000111839217995342, 0, -0.0432908248371864, 0.00129192164198252, -0.000770509459913362, 7.67133670909187e-05, 3.15978344324762e-05, -2.93394558209848e-06, 0, 0.00854343128810993, -0.00434223503010926, 0.000496337142121929, -1.31251600980501e-05, 8.65722000607495e-06, 5.86638630464148e-07, 6.12594488753280e-08, 0, -0.0654466050275388, -0.00273729684245883, 3.05028125870384e-05, -1.37401587879031e-07, 5.74989499675812e-07, -3.58609499372689e-07, -1.50030298656803e-07, 3.45568665613545e-08, 0, -0.0121405408466051, -0.00163781893784001, -5.17485167430442e-05, 5.50854763054154e-06, 1.40595802940089e-06, -9.02712801219109e-08, -2.43178518154195e-08, 1.10182025929641e-09, 5.52583995382292e-10 };
            double[] btm_amp4 = new double[55] { 0, 0, -0.153069712160729, 0, -0.0594593279256315, -0.0148049746605976, 0, 0.000690578822448154, 0.00737272003275804, -0.00465992615639334, 0, 0.0123552841751027, 0.00351252210495320, -0.00492345590863009, 0.00118736621303254, 0, -0.0163130386367319, 0.000466546622785591, -0.000254641911212074, 0.000257788323526059, 3.47389019706321e-05, 0, 0.00958575882905318, -0.00300223048719657, -0.000824329705257649, -6.94163109021607e-05, 1.81867749556230e-05, -5.55979315996809e-06, 0, -0.0123973970235239, -0.00400925522496225, -5.15373771874713e-06, -0.000107237568280748, -1.73117542186820e-06, -1.97738760565604e-06, 5.65788127065801e-08, 0, 0.00140627852636228, -0.00247153171376130, -0.000226377221830705, -5.70208797023784e-05, 3.39698594789969e-06, 3.64449063896633e-07, -9.77718383074134e-08, 1.82201788126035e-08, 0, 0.0104546503530950, 0.000417919412278803, -0.000168919901607586, -8.19393039432030e-06, 2.32808659060194e-07, 2.25925124973257e-07, -2.49175091377898e-08, 3.50446433655499e-09, -1.94070436075581e-10 };
            double[] btm_amp5 = new double[55] { 0, 0, -0.318067710502201, 0, -0.0579970550611717, -0.0163148672150660, 0, -0.0247995310482872, 0.00184058104759062, 4.78971819911175e-05, 0, -0.0171073512965450, 0.00365130610888561, 0.00145783128202004, -0.000226881889946824, 0, 0.00755674647985190, 0.000514957580615413, 0.000759533035273623, -7.75857263305171e-05, 4.63062748297388e-06, 0, 0.0226092207361425, -0.000291965510756393, 4.37391342224835e-05, -2.84779565213827e-05, -1.65395117249092e-05, -4.77468452947909e-07, 0, -0.00623867872781672, 0.000271609462267271, 3.20861851847977e-05, -2.16697697948683e-05, -1.44145597656715e-06, 1.24486068634153e-06, -6.28426546295651e-08, 0, 0.00227576760609467, -0.000145778705425263, -6.75672730446659e-05, 3.66978040337151e-06, 4.83940851973245e-07, 1.77643240321121e-08, 4.55141728088402e-08, -1.38950422298613e-09, 0, 0.000640225738785700, 0.000109943699032360, -4.60170764447540e-05, 2.72518830703328e-06, 2.60096032033877e-07, 2.24172342768408e-08, -7.13834824083231e-09, -5.05421486538336e-10, 4.98503970427622e-10 };
            double[] btm_amp6 = new double[55] { 0, 0, 0.0436132188092647, 0, -0.0246484999501010, -0.0178634979743666, 0, -0.00966695333812173, -0.00205399617586783, -0.00324902800968307, 0, 0.00980529908298968, -0.00109467788276475, -0.000793675066756176, -0.000749623746720517, 0, -0.000156427285293542, -0.000460784039751379, 0.000181430188608916, 0.000104733632507062, -7.30321479528749e-05, 0, -0.00558075912172978, 0.000767300353102789, -1.88154652652516e-05, -1.14727220146119e-06, 1.90605770654750e-05, -6.13104399536983e-07, 0, 0.00531032179297282, -0.000407391318433965, -0.000107814556874618, -1.53926679728800e-05, -3.55625229117244e-07, 5.03753366147334e-08, 2.31271308250387e-08, 0, -0.00101323304224313, -0.000614150635714083, 1.60698789132012e-05, -1.82764827340315e-06, -1.72271878392577e-06, 1.43298729059203e-07, 1.30566132758761e-08, 9.46777156623161e-09, 0, 0.00199571645844959, 0.000821834795051578, 2.23745005788397e-05, -4.30913839487089e-06, 1.72890179447845e-07, -5.33871165314281e-08, -2.92212234771776e-09, -5.73455493122187e-10, 6.49711127030057e-10 };

            double alpha2 = -0.00506964011908224;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata1 = 0; double ata2 = 0; double ata3 = 0; double ata4 = 0; double ata5 = 0; double ata6 = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata1 = ata1 + (atm_amp1[i - 1] * aP[i - 1] + btm_amp1[i - 1] * bP[i - 1]);
                ata2 = ata2 + (atm_amp2[i - 1] * aP[i - 1] + btm_amp2[i - 1] * bP[i - 1]);
                ata3 = ata3 + (atm_amp3[i - 1] * aP[i - 1] + btm_amp3[i - 1] * bP[i - 1]);
                ata4 = ata4 + (atm_amp4[i - 1] * aP[i - 1] + btm_amp4[i - 1] * bP[i - 1]);
                ata5 = ata5 + (atm_amp5[i - 1] * aP[i - 1] + btm_amp5[i - 1] * bP[i - 1]);
                ata6 = ata6 + (atm_amp6[i - 1] * aP[i - 1] + btm_amp6[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata1 * Math.Cos((doy) / 365.25 * 2 * Math.PI) + ata2 * Math.Sin((doy) / 365.25 * 2 * Math.PI) + ata3 * Math.Cos((doy) / 365.25 * 4 * Math.PI) + ata4 * Math.Sin((doy) / 365.25 * 4 * Math.PI) + ata5 * Math.Cos((doy - Math.Floor(doy)) * 24 / 24 * 2 * Math.PI) + ata6 * Math.Sin((doy - Math.Floor(doy)) * 24 / 24 * 2 * Math.PI);
            double Tm = Tm0 + alpha2 * hort;
            return Tm;

        }

        /// <summary>
        /// GWMT-3(初始相位估计，考虑天变化，考虑季节性变化)
        /// </summary>
        /// <param name="doy"></param>
        /// <param name="lat">度</param>
        /// <param name="lon">度</param>
        /// <param name="h">米</param>
        /// <returns></returns>
        public static double GetTm_GWMT3_C_SD(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { 278.913193848046, 2.14952543386368, 0.590789951076254, -23.7213475061307, 0.865642226411834, 0.0782382577006348, 1.34012208848988, 0.197327018477427, -0.00374386907819695, -0.0308249104499286, -3.97906506245375, 0.378816507139967, 0.0155040680520617, -0.000286816384361236, -0.00343630532919808, 1.11341593352818, -0.100206079500838, 0.0443266833648849, -0.000620034286597984, 0.00226759278249950, -0.000231088059791540, 1.58441604650407, -0.0243976734044269, 0.0371838368751335, 0.00653792980667827, 3.08511207187290e-05, 3.07281150987728e-05, 4.88432268162372e-06, 0.658528475507866, 0.129957878033514, 0.0249722924756752, 0.00243305133965742, -0.000131664700018163, -1.42020396848410e-05, -2.40136412894800e-06, 4.27112768364887e-07, -2.47060111705598, -0.0626492026763748, 0.00463854836684654, 0.000714667291416253, 5.38015428656954e-06, -1.91356566000911e-05, 4.64958381368815e-07, 6.69929577123813e-07, -6.42726062126192e-08, -0.663053708783979, 0.0507496271932276, 0.00304776299111337, 0.000200044068193767, -7.97751992722506e-05, -5.58171298409409e-06, 1.09157548354841e-07, 1.43126070201652e-07, 3.21530777468248e-08, -2.01672122627877e-09 };
            double[] atm_amp1 = new double[55] { -1.50357841044008, -6.88535498665941, -0.137081001146590, -2.74578476669115, 0.0498007908531307, 0.156439771615358, -1.52597679196750, 0.337720748453994, 0.172295428760541, -0.0178900014031456, 1.60585918088668, 0.356606715826858, 0.157428740189424, -0.0101077007763269, -0.000758953624150212, 1.05031238099938, 0.367836433921792, 0.0877595133522769, -0.00570688110627029, 6.36113614047229e-05, 8.53705231727064e-05, 1.49173246515930, 0.124908396715594, 0.0411889038396170, 0.00192576065487498, -0.000313247427318225, -3.10427460301061e-05, -2.04296771295984e-05, -2.39110029103442, -0.0374456211633521, -0.00790497344036861, -0.000165534468520236, -8.01213030165241e-05, 2.23894041242404e-05, -7.68583494222148e-06, -1.32233727397584e-06, -0.394103463826602, 0.0467039012650551, -0.00741227326735153, -0.000326216653904973, 0.000107538777757185, 3.70573479760687e-07, -9.50822660945369e-07, -8.90555980226102e-08, -1.24912024025099e-08, 1.30803095013622, 0.0111604212904405, -0.00686458853808507, -0.000435392855776141, 5.36193081911073e-05, -7.47236951093780e-07, -6.66140197942473e-07, -1.07447276962544e-07, -1.67727175868438e-09, 1.01949995971363e-09 };
            double[] atm_amp2 = new double[55] { -0.490443134033246, -3.60816294943748, 0.208940273777585, -1.29240132979539, 0.0651764594545999, -0.0671919696883485, 0.256550950701283, 0.124736639219699, -0.00744971903457042, 0.00372968802120277, 0.647702947139525, 0.0703705747938715, 0.0348943113365899, -0.00190164454435747, 0.00464005523379215, 1.27942465506500, 0.0685230399732661, 0.0208336453374108, -4.69831771879821e-05, 0.000160270705677743, 0.000139111015496430, 0.0171053520324283, -0.0449766123216264, 0.0190704460941207, 0.00238656008834707, 0.000121471548016555, -2.18113847448740e-05, -7.33574182568625e-06, -1.58998350252061, -0.0328191115554504, 0.000342356947737002, 0.00118323297536220, 3.33350938670129e-05, -2.15636426345593e-07, -2.61230823022943e-06, 1.22257165504839e-07, -0.343001723325573, 0.0260803828602906, 0.00364735778967740, 0.000156106986156210, -8.27248758462458e-05, -4.57148276079503e-07, 4.17608009519649e-07, -1.22780724171146e-08, 3.19793728909667e-08, 1.18600524771828, 0.0292564483452499, -3.20225196726696e-05, 0.000177647959534783, -5.65628780619150e-05, -2.44248118294045e-06, 2.52083516532592e-07, -1.33324552096752e-08, 1.26859164043641e-09, 9.54852622598599e-10 };
            double[] atm_amp3 = new double[55] { 0.123015226572523, 0.0588307218149931, -0.100742387914827, 1.03172224588968, -0.0302830488638100, 0.0308862967907810, 0.177577664395732, 0.000693296392958535, 0.0243931345210487, -2.06920369100048e-05, 0.905267089704121, 0.0267476086179358, 0.00271704561644648, -0.00196077156005403, 0.000235860887822959, -0.124856691058800, -0.0667613679800032, -0.00102170877756708, 0.00109360134351759, -0.000523997862060589, 5.19453778571945e-06, 0.282140304620344, -0.0315155536480122, -0.000837559119142980, -0.000296092095529610, -0.000141860360137691, -1.91692967531095e-05, -5.13664257061122e-06, -0.250523311211463, -0.00999570534303913, 0.000290030821689314, 0.000270191215337656, -3.52302819732976e-05, -8.93630500464091e-06, -1.45487144079627e-06, -4.42772686108840e-08, 0.149429160613631, 0.0577355155019533, -0.000979087149386315, -0.000181830798912691, -3.32168416639679e-05, -1.95537788209921e-06, -3.65287484071859e-08, -8.77930299165221e-08, -4.75870388301098e-09, -0.0108381557293928, 0.0523578100337973, 0.000342166538341685, -0.000231131723685654, -9.32439017639858e-06, -1.00740918272360e-06, 1.44039981528973e-08, 5.86805195181152e-09, -3.23163987026797e-09, -4.80724316641188e-10 };
            double[] atm_amp4 = new double[55] { 0.183761659510732, 0.206274553801548, -0.0332190024291030, 0.466508710235489, -0.0424520247473439, 0.0223976105331721, 0.460472535424853, -0.102139694569627, 0.0247806948296794, -0.00107632256550731, -0.334713042750430, -0.00816914734071095, 0.0115475982759477, 0.00192297860173393, -0.000121799111734604, -0.188545713770715, -0.0519763851599025, 0.0110044118277014, 0.00131297446187848, -0.000315734572351223, -9.78124497588912e-05, 0.158969888730169, 0.0210951166140767, -0.00614931621928090, 0.00171446963146785, -0.000117657562363885, -1.83342381915187e-05, -1.02433287033910e-06, 0.0734325183226186, 0.0429313535974868, -0.00141835911451616, -0.000986110137613478, 3.12770961723526e-05, -2.21936699294524e-05, 3.95714928703495e-07, -1.10366762527142e-07, 0.102202261290167, 0.0453626644735104, -0.00178124052673975, 3.17973520429082e-05, 1.47854180527288e-05, -7.08133872527112e-06, 1.90092759800060e-07, 2.45970889852777e-09, 1.49196579866235e-08, 0.211274857270313, 0.0363550619611559, 0.000403699667612830, 0.000231555475041575, -1.85193189517214e-06, -2.45921139509727e-06, 6.02651798249835e-08, 1.77967820317953e-10, 4.79835500602423e-09, -8.35320309820107e-11 };
            double[] atm_amp5 = new double[55] { 0.0264745865644508, 0.0636281326076206, 0.00406221921099485, 0.0587104647500856, 0.00795108239330409, 0.00492735439276952, 0.0230042177278044, 0.00338751541269664, -0.00263631506132007, -0.00117445664187240, -0.0855072913755763, -0.00842210141808304, -0.00996214256889084, -9.62838499229318e-05, 5.29830239544405e-05, -0.0791184999493572, -0.0144480414868246, -0.00901521352131058, 0.000635870224332767, 0.000123945040976053, 5.74323667375163e-06, 0.0930326000192725, 0.00934129731524048, -0.00510281003560530, 0.000155563008543744, 0.000147692119094094, -1.57079082594668e-06, 3.51826084445241e-07, -0.0837991058501467, -0.0169133227319184, -0.00322143486686872, 0.000465727916801133, 7.65699262419331e-05, 3.42463533182480e-06, 2.08346005106000e-07, 2.37014781378799e-08, -0.0792196933811768, -0.0103846822765473, -0.00298873546979937, 0.000347207715437184, 2.94603486596977e-05, 9.25238799721361e-07, -5.24263840860928e-08, -4.01246197155309e-08, 9.88474732252493e-10, -0.00103940034785351, -0.00667860570968108, 0.000711815946077160, 0.000275926164731938, 9.95699701035181e-06, 2.82026393592593e-07, -6.52279895929276e-08, 1.41781706175705e-08, 3.07320566908440e-09, 3.43769814150791e-11 };
            double[] atm_amp6 = new double[55] { 0.0189977019043771, 0.0451149534510235, -0.00475409863078388, 0.0798110866210061, 0.00766445387726839, -0.0179949811805477, 0.0240712809862496, 0.0268033487567655, -0.00490501346018315, 0.00442556346694415, -0.0549192395696373, 0.0168279618015404, 0.00243083710203148, 0.000904066848374302, 0.000442022090761244, -0.141707586494004, 0.0274223420397656, -0.00515435479403153, 0.00174997453226588, -2.61284210808893e-05, 2.04083600229863e-05, -0.00292182383321608, 0.0194333799711075, -0.00242100767660910, 0.000535257487995504, 1.05996927795981e-05, 7.49267791782869e-06, 1.79069649724995e-06, -0.128658616053863, 0.00166546649259100, -0.00352137415810433, 0.000334370673549209, -2.50828572091204e-05, 3.73726711940752e-08, 7.05219161310594e-07, -2.36126733646477e-07, 0.0473024773494289, 0.00105930110837466, 7.46081302620343e-05, -4.42394062421324e-06, 3.48134688085541e-05, -1.28690952021343e-06, 6.02953915964343e-07, 4.85044751412502e-09, 2.48726748546505e-10, 0.0298715734198243, 0.00480328455771327, -0.000915956697492851, 0.000258761922829618, 3.47613439655327e-06, -3.36075436725926e-07, 2.28750695323047e-07, -7.88947077015057e-09, -2.07299564168563e-09, 3.49421712534000e-10 };
            double[] atm_amp7 = new double[55] { -0.0205617229345367, -0.0231485420459602, -0.0524563982215307, -0.0174700605681008, -0.0139312886719646, -0.00428446255676064, 0.0289417615401890, 0.0121393964707090, 0.00534112003934187, -0.00225727799171830, 0.0269351331433286, 0.0102973482816956, 0.00168671414975431, 0.00185694203349048, 0.000324620114109390, 0.00474575544947465, -0.00351645865271073, -0.00133623697246118, 0.000128365429610617, -3.64131944746647e-06, 6.02792147906005e-05, -0.0302546827614798, 0.000344790223108408, -0.000400360442009885, -0.000257087039740720, 1.52198201317517e-05, -2.65899286541509e-06, 4.12534640508962e-06, 0.0273684512339350, -0.00206738173018941, 0.000347053212214047, 2.16383057699819e-05, 1.35612995822763e-05, -3.25583149169873e-06, -5.99829699114235e-07, 2.55285432874129e-07, 0.0466895190971581, 0.00107937713366547, 0.000616209148510458, -2.26202870355222e-05, 9.20906915757949e-07, -7.11862903934235e-07, -4.91266804887747e-08, -7.56185887677958e-08, 7.43795899257664e-10, -0.0443928752789281, 4.64455719091727e-05, 1.20723584704102e-05, 5.48431407003505e-06, 2.28399256800357e-06, 5.98654236280482e-07, -5.47915083338683e-08, 1.79899033311899e-08, -1.35035335304060e-09, -4.15545717360367e-10 };
            double[] atm_amp8 = new double[55] { -0.0336801517973625, -0.0132874923677592, -0.292432001168188, 0.0444614176682940, -0.0211611486226644, -0.0180129457180665, 0.0227856588579806, 0.0150354130747620, -0.00443115951416864, 0.00143931501444481, -0.0262696864770178, -0.00896664805856366, 0.000925214599586068, -0.000629362342556666, 1.25070808540989e-05, -0.0184576423943509, -0.00603109650242930, -0.000136599444756620, 0.000363722259601989, 3.83843515370330e-05, 1.75277400507863e-05, 0.0166813888144431, 0.00790880783221276, 0.000254400367714979, 0.000333083774515378, -3.39186993299301e-05, -1.02786463082341e-05, 1.76209528902088e-06, 0.00766282420552907, -0.00775106348009302, 0.00101793053369397, -3.41950427098231e-06, -6.19461604566960e-06, -1.96938257211453e-06, -4.11768586834891e-08, 1.12048379307216e-07, -0.00733847079052747, 0.00399006648892063, -0.000414658510228897, -1.87725501842202e-05, 4.07109889298593e-06, 3.95370149658799e-07, -9.49701902725546e-08, -6.13528938038656e-09, 1.21410179235665e-08, -0.00721087735455677, 0.00227735826430621, 9.22822077149140e-05, 8.14297565080125e-06, -3.67025715049572e-06, -5.35815612381665e-07, 8.65023388668505e-08, -3.41053138349361e-09, -5.01692410187479e-09, 1.00507808234328e-10 };
            double[] btm_mean = new double[55] { 0, 0, 0.0778439559035029, 0, 0.305724855105514, 0.181802202950849, 0, -0.392794713422779, 0.117499691624361, 0.0165898148481980, 0, 0.274728543127716, 0.0440552693018674, -0.00119772016901732, 0.00102867487265618, 0, -0.271256395115917, 0.0381864850505851, 0.000623576885655421, -0.00171956056402970, 0.000142016659030916, 0, 0.316282844679181, 0.0220631589369796, -0.00578441444596545, -0.000447346046248007, -6.79728371779957e-05, 8.56674060560503e-06, 0, 0.0606544053468970, 0.00249079765837768, -0.00234442563589474, -0.000200617906708535, 2.91858860070685e-05, -6.88306930657430e-07, -1.15686474226260e-06, 0, 0.104691782534193, 0.00269037704919920, 0.000218925747679552, -0.000111455556069689, 1.33598123440345e-05, 2.14384339379336e-06, -9.97443070034353e-08, -1.08823334114525e-07, 0, -0.133141963710335, -0.00414220630944287, 0.000262855841139334, -1.10670233243914e-05, 3.29311749008211e-06, 6.30555881364118e-07, -1.10014036844813e-07, 9.60133780672756e-09, -1.66666907085690e-10 };
            double[] btm_amp1 = new double[55] { 0, 0, -0.592544323137277, 0, -0.756830285186494, -0.120466800590811, 0, -0.497337639950023, 0.0429758412524005, -0.00880246284406259, 0, -0.105957691018132, 0.0152513491962198, -0.0206492870123072, -0.00201480186663281, 0, 0.234673408257706, 0.0343234842014141, -0.0140078911404396, -0.000649530912946837, 7.37198947552686e-05, 0, 0.0584480892525143, 0.0320634897445019, -0.00519339425815415, -0.000214696525208994, 0.000121882602894708, -5.91338315256321e-06, 0, 0.215467920452235, 0.00758007272948335, -0.00299821365666197, -0.000199149633751028, 6.29305458804400e-05, -1.90157231802991e-06, -1.22581009671105e-06, 0, 0.0226862844295569, -0.00756239050964776, 0.000397727627485262, -0.000156798520460423, 1.00241299604369e-05, -8.09979136286393e-07, -1.16049714079660e-08, -4.65263255039175e-08, 0, 0.0445934832600392, 0.000477680787076553, -4.12932028490717e-05, 1.38881291532766e-05, 8.72241755725126e-06, -1.26393049515457e-06, -9.95237582135601e-08, -1.80697395514393e-10, 4.28305344079233e-10 };
            double[] btm_amp2 = new double[55] { 0, 0, -0.0122479225629859, 0, 0.0201764718351105, 0.0269100037877475, 0, -0.0803804083262805, 0.00846881581105832, -0.00525517432456628, 0, -0.0967410834510930, 0.0151041277869198, -0.00633577013408577, -0.00280633067368284, 0, 0.0902200068683965, 0.0123487652827539, -0.00749518160894458, -1.00592181888477e-05, -0.000166141256175507, 0, 0.0433209756597199, 0.0130063541545713, -0.00303008074121783, 9.61271441175123e-05, 1.35171362821044e-05, -4.13238244989500e-06, 0, -0.0298780940642469, -0.0107315290836521, -0.000197362811594634, -0.000128792440594722, -6.93538887113021e-06, 3.52999295727555e-06, 6.99073985751360e-07, 0, -0.0119903222110207, -0.00435139155486781, -0.000432695216764790, -3.34792803193591e-05, -5.55435596506353e-06, 2.06143749557052e-07, 3.27163078208933e-08, 1.54402067798689e-08, 0, -0.0223419048924810, -0.00453735197870800, -0.000497953048194449, -1.75672849601439e-05, 9.94876496626340e-08, -2.00940341987441e-07, 6.95790293647312e-08, -1.35303491629338e-08, -4.67939008729884e-10 };
            double[] btm_amp3 = new double[55] { 0, 0, -0.133767821533148, 0, -0.0885885248540713, 0.0133775788275662, 0, 0.0724691190246563, -0.00204473637060554, -0.00343108320370806, 0, -0.0239673580518013, 0.0106923052688022, 0.000698524162466895, 0.000351019880517109, 0, 0.0705424363361910, 0.00132609772250316, -0.000256210026555086, 0.000442905837390443, 0.000111837956408083, 0, -0.0432791962988943, 0.00129156988746648, -0.000770437237902909, 7.67153536166769e-05, 3.15960389976424e-05, -2.93570929187384e-06, 0, 0.00855565942065543, -0.00434250225177128, 0.000496364388070181, -1.31156034868245e-05, 8.65728413551285e-06, 5.86021794949373e-07, 6.12979224305453e-08, 0, -0.0654447517971324, -0.00273576351627449, 3.06341308400599e-05, -1.44362162894974e-07, 5.73754263403623e-07, -3.58701078692997e-07, -1.50029467539803e-07, 3.45551869062121e-08, 0, -0.0121438758116047, -0.00163713191612239, -5.17648317188920e-05, 5.50996139293644e-06, 1.40526588337810e-06, -9.03110435747669e-08, -2.43144171413902e-08, 1.10201591942726e-09, 5.52632831059859e-10 };
            double[] btm_amp4 = new double[55] { 0, 0, -0.153069584724438, 0, -0.0594593928729115, -0.0148049767106777, 0, 0.000690541076930417, 0.00737270976690044, -0.00465992028420767, 0, 0.0123551494924653, 0.00351253429630883, -0.00492345736859305, 0.00118736635820028, 0, -0.0163131597129172, 0.000466547197922588, -0.000254643248816234, 0.000257788368568591, 3.47389099966435e-05, 0, 0.00958570313393658, -0.00300223144234928, -0.000824330089797292, -6.94163228670889e-05, 1.81867718266939e-05, -5.55978867203104e-06, 0, -0.0123974520470925, -0.00400925445535924, -5.15420530267921e-06, -0.000107237630194751, -1.73117539784248e-06, -1.97738464833890e-06, 5.65785642725877e-08, 0, 0.00140626186565624, -0.00247153787699694, -0.000226377887295412, -5.70208498256150e-05, 3.39699095972255e-06, 3.64449134143839e-07, -9.77719054273258e-08, 1.82201910827402e-08, 0, 0.0104546549105564, 0.000417917388371545, -0.000168919847827982, -8.19393959682237e-06, 2.32812038902992e-07, 2.25925271135082e-07, -2.49175333820130e-08, 3.50446342496329e-09, -1.94070581846517e-10 };

            double[] btm_amp5 = new double[55] { 0, 0, -0.0451744697945716, 0, 0.0375287861950410, 0.00700194927941702, 0, 0.0148977859554328, 0.00454025582198326, -0.00138286401293666, 0, 0.0539121042372940, -0.00494966404717545, 0.000912083049807437, -0.000119145544109041, 0, 0.0423319391524412, -0.000244188911092121, 0.000363838051143304, -7.67724705937784e-05, -2.17662750286774e-06, 0, 0.0198175406911063, -0.000572722480805807, 0.000123512398587258, 3.41917838964432e-06, -2.94528043034619e-06, -2.96699354284073e-06, 0, 0.0208080472327492, -0.000450442786614888, 4.97446106048915e-05, 1.64574671833880e-05, 1.05278045605929e-07, -1.05136009239730e-06, 6.61909037506420e-08, 0, 0.00323521182030012, 0.00260149765872007, 0.000224196688649587, -1.18333989838572e-05, -2.09451309000269e-06, -1.52417155189420e-07, 2.06111582619676e-09, -2.90161325192997e-09, 0, -0.00557067675706494, 0.00115850677881200, -2.75413061766485e-05, 2.43704662490943e-06, -1.18014458172373e-06, -6.72990409034591e-08, 5.93360084097450e-09, 3.32677908593996e-10, 8.28254197235512e-11 };
            double[] btm_amp6 = new double[55] { 0, 0, -0.0171110219383818, 0, -0.0337108689877004, -0.0182957610686571, 0, 6.13092577121604e-05, -0.00145137565593209, -0.00285887480854391, 0, 0.000542557230313560, 0.000145237720913024, -0.000977198760961586, 0.000182400413998777, 0, 0.0185351874843692, 5.62517556151807e-05, 0.000508790601039636, 0.000175245326540662, -3.71647849822012e-06, 0, 0.00717340019523024, 0.00290371016650679, 9.72600651228935e-05, 4.94501720850880e-06, 1.23316059375255e-05, 3.47980837060287e-06, 0, 0.00399990624495310, 0.000413582413472590, 0.000407932129916557, 2.59042119075553e-05, -4.06747355872594e-07, -3.89437507471214e-07, 9.72275845039440e-08, 0, 0.0102416948867214, -0.000411098215913500, 0.000127080358951948, -5.90823165905421e-07, 4.17943367515205e-07, 3.74057514843783e-07, 7.58676557943664e-08, -5.84105031375283e-09, 0, 0.0111442938099051, -0.00101811390350116, 2.02762007918495e-05, 4.05031736141454e-06, -4.98088405241335e-07, 2.50370900043687e-08, 1.16682373441531e-08, -3.97795965185250e-11, -2.26353403908053e-11 };
            double[] btm_amp7 = new double[55] { 0, 0, -0.318067710484858, 0, -0.0579970550760156, -0.0163148672123062, 0, -0.0247995310188866, 0.00184058104756523, 4.78971821964659e-05, 0, -0.0171073513207250, 0.00365130611287654, 0.00145783128129642, -0.000226881889940471, 0, 0.00755674651041191, 0.000514957579720145, 0.000759533035678684, -7.75857263580940e-05, 4.63062748497298e-06, 0, 0.0226092207127046, -0.000291965506804858, 4.37391334592384e-05, -2.84779565169789e-05, -1.65395117250188e-05, -4.77468452932902e-07, 0, -0.00623867870283529, 0.000271609460126242, 3.20861857393573e-05, -2.16697698220814e-05, -1.44145597445752e-06, 1.24486068638200e-06, -6.28426546291994e-08, 0, 0.00227576759037940, -0.000145778701196690, -6.75672740459936e-05, 3.66978042189860e-06, 4.83940849707707e-07, 1.77643241069653e-08, 4.55141728059018e-08, -1.38950422317724e-09, 0, 0.000640225745474454, 0.000109943695141736, -4.60170757071842e-05, 2.72518827415679e-06, 2.60096034647963e-07, 2.24172343043828e-08, -7.13834824232191e-09, -5.05421486253264e-10, 4.98503970412482e-10 };
            double[] btm_amp8 = new double[55] { 0, 0, 0.0436132187817903, 0, -0.0246485000546009, -0.0178634979687166, 0, -0.00966695347150607, -0.00205399617313988, -0.00324902801202440, 0, 0.00980529887790559, -0.00109467787467547, -0.000793675067668873, -0.000749623746809104, 0, -0.000156427493609808, -0.000460784031873330, 0.000181430188257050, 0.000104733632555888, -7.30321479163308e-05, 0, -0.00558075934581246, 0.000767300366132662, -1.88154647161680e-05, -1.14727221776227e-06, 1.90605770872725e-05, -6.13104398357657e-07, 0, 0.00531032159990379, -0.000407391303654878, -0.000107814556287519, -1.53926679357626e-05, -3.55625219501707e-07, 5.03753366483834e-08, 2.31271306264790e-08, 0, -0.00101323333533458, -0.000614150606747601, 1.60698791202946e-05, -1.82764826283463e-06, -1.72271878443320e-06, 1.43298729224472e-07, 1.30566131178279e-08, 9.46777155846731e-09, 0, 0.00199571618048580, 0.000821834825112338, 2.23745003506586e-05, -4.30913838164879e-06, 1.72890177203190e-07, -5.33871168128225e-08, -2.92212240142906e-09, -5.73455496281505e-10, 6.49711127711701e-10 };
            double alpha2 = -0.00506964011908224;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata1 = 0; double ata2 = 0; double ata3 = 0; double ata4 = 0; double ata5 = 0; double ata6 = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata1 = ata1 + (atm_amp1[i - 1] * aP[i - 1] + btm_amp1[i - 1] * bP[i - 1]);
                ata2 = ata2 + (atm_amp2[i - 1] * aP[i - 1] + btm_amp2[i - 1] * bP[i - 1]);
                ata3 = ata3 + (atm_amp3[i - 1] * aP[i - 1] + btm_amp3[i - 1] * bP[i - 1]);
                ata4 = ata4 + (atm_amp4[i - 1] * aP[i - 1] + btm_amp4[i - 1] * bP[i - 1]);
                ata5 = ata5 + (atm_amp5[i - 1] * aP[i - 1] + btm_amp5[i - 1] * bP[i - 1]);
                ata6 = ata6 + (atm_amp6[i - 1] * aP[i - 1] + btm_amp6[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata1 * Math.Cos((doy) / 365.25 * 2 * Math.PI) + ata2 * Math.Sin((doy) / 365.25 * 2 * Math.PI) + ata3 * Math.Cos((doy) / 365.25 * 4 * Math.PI) + ata4 * Math.Sin((doy) / 365.25 * 4 * Math.PI) + ata5 * Math.Cos((doy - Math.Floor(doy)) * 24 / 24 * 2 * Math.PI) + ata6 * Math.Sin((doy - Math.Floor(doy)) * 24 / 24 * 2 * Math.PI);
            double Tm = Tm0 + alpha2 * hort;
            return Tm;

        }

        /// <summary>
        /// GWMT-G(05~11)
        /// </summary>
        /// <param name="doy"></param>
        /// <param name="lat">度</param>
        /// <param name="lon">度</param>
        /// <param name="h">米</param>
        /// <returns></returns>
        public static double GetTm_GWMT_G(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { 278.913185469844, 2.14946661239271, 0.590853551131170, -23.7216544430433, 0.865653463142445, 0.0782097445596184, 1.34017302342519, 0.197320089676039, -0.00376188141382163, -0.0308230769665850, -3.97931933264498, 0.378798379265376, 0.0155006744638567, -0.000285782104850616, -0.00343579527757031, 1.11355260130035, -0.100195208360265, 0.0443269513370102, -0.000620188144615561, 0.00226773968291617, -0.000231080893916107, 1.58423232346560, -0.0244038604637486, 0.0371855355961861, 0.00653814918405110, 3.08873448282741e-05, 3.07327211890884e-05, 4.88589896379095e-06, 0.658575208243383, 0.129964973663128, 0.0249738306218480, 0.00243299083454219, -0.000131667676598473, -1.42018388520606e-05, -2.40089731629376e-06, 4.27200034448935e-07, -2.47063412432994, -0.0626626827111737, 0.00464055419687585, 0.000714654419292605, 5.36452817211747e-06, -1.91355093143817e-05, 4.65086401335140e-07, 6.69977404640466e-07, -6.42675660233558e-08, -0.662993681726140, 0.0507398461518682, 0.00304785300314746, 0.000200079252879880, -7.97861358549025e-05, -5.58177885821145e-06, 1.09237752225326e-07, 1.43126016719917e-07, 3.21537211374070e-08, -2.01654193660281e-09 };
            double[] atm_amp = new double[55] { -1.56550982203637, -7.77131706975356, -0.0303820928339602, -3.03486956095009, 0.0734169136813310, 0.110561089617108, -1.25517098718765, 0.358050202779545, 0.151212734656531, -0.0143954191039285, 1.72630311135324, 0.350920575829973, 0.156625871251584, -0.00990541524680594, 0.00137177205780904, 1.50807628379547, 0.360251512992474, 0.0879284669272250, -0.00514001946517561, 0.000128158910679475, 0.000138098742845892, 1.34525009268668, 0.0921195561379710, 0.0453807023650197, 0.00278308695434774, -0.000227189471088512, -3.74756797159697e-05, -2.15649272083144e-05, -2.84762142800454, -0.0480770580596760, -0.00693562528490446, 0.000374789495614687, -5.71355335751490e-05, 1.99854465054942e-05, -8.04810374899740e-06, -1.13201942601719e-06, -0.505243133383643, 0.0533914570188155, -0.00503149273815219, -0.000223500162120112, 5.98557830155555e-05, 1.30067285013882e-07, -6.67882088009258e-07, -8.52480479798344e-08, 2.93992606062327e-09, 1.69778275826363, 0.0229346687545256, -0.00617112992730979, -0.000311937677784738, 2.30659886637585e-05, -1.75002387685119e-06, -4.85823595805503e-07, -1.02277662376870e-07, -9.41774728919763e-10, 1.33730122449160e-09 };
            double[] btm_mean = new double[55] { 0, 0, 0.0779321904540482, 0, 0.305787867337052, 0.181806670816364, 0, -0.392799583940490, 0.117497931818546, 0.0165912469690421, 0, 0.274712319473989, 0.0440545017989369, -0.00119784572264086, 0.00102843105933468, 0, -0.271292871606482, 0.0381855275116478, 0.000623430204835655, -0.00171964048480232, 0.000141963684859922, 0, 0.316289330854242, 0.0220625495087088, -0.00578428614425305, -0.000447348518518146, -6.79863695040047e-05, 8.56830987786521e-06, 0, 0.0606308315214112, 0.00249044007242830, -0.00234442940758269, -0.000200622497021060, 2.91792780107225e-05, -6.87647836582390e-07, -1.15676586051069e-06, 0, 0.104706295345845, 0.00269027716980879, 0.000218780462569248, -0.000111446885765488, 1.33592339376619e-05, 2.14407536655100e-06, -9.96985720210329e-08, -1.08828422752409e-07, 0, -0.133140594157684, -0.00414266251565057, 0.000262824844661477, -1.10718859923940e-05, 3.29257356521206e-06, 6.30659176173814e-07, -1.09996799505129e-07, 9.59933515477674e-09, -1.66921319343411e-10 };
            double[] btm_amp = new double[55] { 0, 0, -0.536761123322134, 0, -0.669902755492018, -0.0961343132192540, 0, -0.481662741487816, 0.0422873011321712, -0.0102160947704275, 0, -0.137873154890229, 0.0203561445763664, -0.0213220398615997, -0.00304811717095408, 0, 0.250315879708555, 0.0362434808554036, -0.0158786430022634, -0.000587276196030311, -7.42630734747483e-06, 0, 0.0715824201711529, 0.0345083014437321, -0.00599762572918842, -0.000150075787187585, 0.000115259807231044, -7.12877446406308e-06, 0, 0.180019572437560, 0.00205378170090498, -0.00277639749489654, -0.000235581085655717, 5.33664303743460e-05, -1.43565575204806e-07, -7.90159007265715e-07, 0, 0.0150832814311839, -0.00870559154044698, 0.000165150110647249, -0.000155439860389865, 6.53304038082364e-06, -6.34985053329990e-07, 4.16013856483446e-09, -3.49105865070948e-08, 0, 0.0301242953725098, -0.00157897172649917, -0.000257281206206968, 4.67925630114407e-06, 7.86565967888685e-06, -1.22239985451874e-06, -5.84588665170677e-08, -6.14705808135190e-09, 1.76917459492606e-10 };
            double alpha2 = -0.00506965435600882;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata = ata + (atm_amp[i - 1] * aP[i - 1] + btm_amp[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata * Math.Cos((doy + 1 - 28) / 365.25 * 2 * Math.PI);
            double Tm = Tm0 + alpha2 * hort;
            return Tm;

        }

        /// <summary>
        /// 二代GWMT模型
        /// </summary>
        /// <param name="doy"></param>
        /// <param name="lat"></param>
        /// <param name="lon"></param>
        /// <param name="h"></param>
        /// <returns></returns>
        public static double GetTm_TNewGWMT(double doy, double lat, double lon, double h)
        {
            lat = lat * Math.PI / 180.0;
            lon = lon * Math.PI / 180.0;
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };

            double[] atm_mean = new double[55] { 278.160684125814, 0.717815044371150, 0.634729257710879, -20.6515652901551, 0.921756898311530, 0.110473040136191, 0.0460198181217136, 0.199996552738270, -0.0388377202245227, -0.0434545323081504, -3.13754197012970, 0.255807985804107, 0.0385776906523917, -0.0142717844062464, -0.00299328405889563, 0.833189813994960, -0.00523234999242524, 0.0753666000267495, 0.000651056325873244, 0.00370600962318829, 0.000252423335697313, 1.69352546152779, 0.0436064501222088, 0.0404884559714365, 0.000885561693056649, -0.000113278227208964, 0.000232256555677016, 6.50527974959141e-07, 0.463078942571176, 0.149776750017934, 0.0194410416918268, 0.00153876503401987, -0.000121583806630846, -0.000107281679957531, 6.11942429689847e-06, -1.25924839297660e-06, -1.26644692765649, 0.0120317046107659, 0.00548479385299236, 0.00196915572402197, 0.000122158317253191, 6.48254665262338e-06, 2.38657529767418e-06, 1.12813935257865e-06, -1.53410594745704e-07, -0.224916211732440, 0.115742262861913, 0.00552144188004023, -0.00133783416473198, -2.01478001668799e-05, -1.54241653640824e-05, 1.52947215936145e-06, 4.15377320216611e-07, -4.16603984660601e-08, -1.18619796602320e-08 };
            double[] atm_amp = new double[55] { -1.62781598556759, -7.48660760879415, -0.0814355069689845, -3.13216175311355, -0.0396907414962157, 0.210381536408435, -0.668233558504951, 0.306167924924459, 0.195818920040657, -0.00991726340358212, 1.67303599255962, 0.375388374036718, 0.192352387525969, -0.00944173062798565, 0.000388270603119768, 0.846021735489891, 0.428759841108646, 0.0999903136049652, -0.0102842700305648, 0.000378414809934223, 0.000150896930626613, 1.45713982649875, 0.105324886898962, 0.0487426811693150, 7.17202151068542e-05, -0.000307371386222559, -2.77808637993578e-05, -1.03369709696449e-05, -2.08429180802025, -0.0459665790008194, -0.00437258808898685, -0.00157501420933758, 5.52977263279935e-05, 4.21825073170814e-07, -9.13031696032519e-06, -2.33542000033037e-07, 0.128435124847858, 0.123064311424512, -0.0119477583576271, 2.75077894808220e-05, 0.000252808970770654, -3.50604416940553e-05, -8.11170154506325e-07, -1.87295348075318e-07, 2.30319177215326e-08, 1.12175451320812, -0.0272857023206622, -0.00397190712348810, -0.000194310357166078, 4.55920904247271e-05, -1.93606536831413e-06, -1.54668209830681e-06, -1.88226857140000e-07, 5.17412976744516e-09, 5.42239433229073e-09 };
            double[] btm_mean = new double[55] { 0, 0, 0.190797942191120, 0, 0.0517578163716600, 0.119177359025331, 0, -0.685504647935312, 0.144742665148485, 0.0283218455260032, 0, 0.220956401760453, 0.114674648804072, 0.00112857564015427, 0.00479775522881844, 0, -0.249003904696560, 0.0296616294861743, -0.000763577400619074, -0.00315642690088921, 0.000269400231895226, 0, 0.335581392918926, 0.0213109457226316, -0.00653507027184844, -0.000779389280421797, -0.000202324607702491, 3.39507667547062e-06, 0, 0.0207759628619078, -0.0126697132614236, -0.00232736254003874, -0.000368559166575988, -2.67647986027959e-05, -1.33474378958339e-06, -1.93660456832981e-06, 0, 0.0727089964324983, 0.0158125363338784, 0.000501708020499228, -0.000133730224530084, 3.24742630703473e-05, 6.37181663312361e-06, 8.82394313998902e-08, -1.89551295936767e-07, 0, 0.0487462425537070, -0.0141586861284804, 0.000827793200871105, -0.000108113289744058, 1.05426604364905e-05, 8.22064264722256e-07, 1.93469841330209e-07, 8.99613585347204e-09, 2.39786535543075e-09 };
            double[] btm_amp = new double[55] { 0, 0, -0.658822303916824, 0, -0.836753321299174, -0.0481135799950949, 0, -0.435367920259599, 0.0632088817133106, -0.0148026444663424, 0, -0.0111156024846691, 0.0257839474988920, -0.0283506523037331, -0.00476390051140994, 0, 0.142255179850165, 0.0419245010517197, -0.0154521872705380, -0.00136111480729734, -1.04405752492178e-05, 0, 0.0539713509053321, 0.0217023885343067, -0.00496355828814161, -0.000549928975197022, 4.34871952527094e-05, 1.29990115979430e-05, 0, 0.114947326950462, -0.00586036478339023, -0.00235457485055852, -0.000425894147199707, 5.54082485977237e-05, 3.42797450234290e-06, 2.00575677564854e-06, 0, 0.0361976478562377, -0.00614960069758884, 0.000799928554153359, -0.000215594779171265, 1.46658528878378e-07, -1.31046597954090e-06, 7.23014357196187e-07, -6.33563876385394e-09, 0, 0.0889756186649709, 0.00689894389360620, -0.000692992344778871, -7.37354530071784e-06, 8.59720920949337e-06, -1.67776066590439e-06, 1.57899115366094e-07, 3.76138909119173e-09, -7.32887615375527e-09 };
            double alpha2 = -0.00598953981362790;



            double t = Math.Sin(lat);
            //% degree n and order m
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            //% determine n!  (faktorielle)  moved by 1
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            //% determine Legendre functions (Heiskanen and Moritz, 
            //% Physical Geodesy, 1967, eq. 1-62)
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            //% spherical harmonics
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * lon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * lon);
                }
            }
            //% Geoidal height
            double undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }

            //orthometric height
            double hort = h - undu;

            //Surface temperature on the geoid
            double atm = 0; double ata = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (atm_mean[i - 1] * aP[i - 1] + btm_mean[i - 1] * bP[i - 1]);
                ata = ata + (atm_amp[i - 1] * aP[i - 1] + btm_amp[i - 1] * bP[i - 1]);
            }
            double Tm0 = atm + ata * Math.Cos((doy + 1 - 28) / 365.25 * 2 * Math.PI);
            double Tm = Tm0 + alpha2 * hort;
            return Tm;





        }

        public static double II(double Tm)
        {
            double Rw = 4.61;
            double k3 = 374700;
            double k2_ = 23.33739;
            double ii = 0;
            ii = Math.Pow(10, 6) / (Rw * (k3 / Tm + k2_));
            return ii / 1000;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="doy">年积日</param>
        /// <param name="dlat">纬度（弧度）</param>
        /// <param name="dlon">经度（弧度）</param>
        /// <param name="dhgt">大地高（米）</param>
        /// <param name="pres">压强（hPa）</param>
        /// <param name="temp">温度（k）</param>
        /// <param name="undu">高程异常</param>
        public static void refGPT(double doy, double dlat, double dlon, double dhgt, ref double pres, ref double temp, ref double undu)
        {
            double[] a_geoid = new double[55] { -5.6195e-001, -6.0794e-002, -2.0125e-001, -6.4180e-002, -3.6997e-002, +1.0098e+001, +1.6436e+001, +1.4065e+001, +1.9881e+000, +6.4414e-001, -4.7482e+000, -3.2290e+000, +5.0652e-001, +3.8279e-001, -2.6646e-002, +1.7224e+000, -2.7970e-001, +6.8177e-001, -9.6658e-002, -1.5113e-002, +2.9206e-003, -3.4621e+000, -3.8198e-001, +3.2306e-002, +6.9915e-003, -2.3068e-003, -1.3548e-003, +4.7324e-006, +2.3527e+000, +1.2985e+000, +2.1232e-001, +2.2571e-002, -3.7855e-003, +2.9449e-005, -1.6265e-004, +1.1711e-007, +1.6732e+000, +1.9858e-001, +2.3975e-002, -9.0013e-004, -2.2475e-003, -3.3095e-005, -1.2040e-005, +2.2010e-006, -1.0083e-006, +8.6297e-001, +5.8231e-001, +2.0545e-002, -7.8110e-003, -1.4085e-004, -8.8459e-006, +5.7256e-006, -1.5068e-006, +4.0095e-007, -2.4185e-008 };
            double[] b_geoid = new double[55] { +0.0000e+000, +0.0000e+000, -6.5993e-002, +0.0000e+000, +6.5364e-002, -5.8320e+000, +0.0000e+000, +1.6961e+000, -1.3557e+000, +1.2694e+000, +0.0000e+000, -2.9310e+000, +9.4805e-001, -7.6243e-002, +4.1076e-002, +0.0000e+000, -5.1808e-001, -3.4583e-001, -4.3632e-002, +2.2101e-003, -1.0663e-002, +0.0000e+000, +1.0927e-001, -2.9463e-001, +1.4371e-003, -1.1452e-002, -2.8156e-003, -3.5330e-004, +0.0000e+000, +4.4049e-001, +5.5653e-002, -2.0396e-002, -1.7312e-003, +3.5805e-005, +7.2682e-005, +2.2535e-006, +0.0000e+000, +1.9502e-002, +2.7919e-002, -8.1812e-003, +4.4540e-004, +8.8663e-005, +5.5596e-005, +2.4826e-006, +1.0279e-006, +0.0000e+000, +6.0529e-002, -3.5824e-002, -5.1367e-003, +3.0119e-005, -2.9911e-005, +1.9844e-005, -1.2349e-006, -7.6756e-009, +5.0100e-008 };
            double[] ap_mean = new double[55] { +1.0108e+003, +8.4886e+000, +1.4799e+000, -1.3897e+001, +3.7516e-003, -1.4936e-001, +1.2232e+001, -7.6615e-001, -6.7699e-002, +8.1002e-003, -1.5874e+001, +3.6614e-001, -6.7807e-002, -3.6309e-003, +5.9966e-004, +4.8163e+000, -3.7363e-001, -7.2071e-002, +1.9998e-003, -6.2385e-004, -3.7916e-004, +4.7609e+000, -3.9534e-001, +8.6667e-003, +1.1569e-002, +1.1441e-003, -1.4193e-004, -8.5723e-005, +6.5008e-001, -5.0889e-001, -1.5754e-002, -2.8305e-003, +5.7458e-004, +3.2577e-005, -9.6052e-006, -2.7974e-006, +1.3530e+000, -2.7271e-001, -3.0276e-004, +3.6286e-003, -2.0398e-004, +1.5846e-005, -7.7787e-006, +1.1210e-006, +9.9020e-008, +5.5046e-001, -2.7312e-001, +3.2532e-003, -2.4277e-003, +1.1596e-004, +2.6421e-007, -1.3263e-006, +2.7322e-007, +1.4058e-007, +4.9414e-009 };
            double[] bp_mean = new double[55] { +0.0000e+000, +0.0000e+000, -1.2878e+000, +0.0000e+000, +7.0444e-001, +3.3222e-001, +0.0000e+000, -2.9636e-001, +7.2248e-003, +7.9655e-003, +0.0000e+000, +1.0854e+000, +1.1145e-002, -3.6513e-002, +3.1527e-003, +0.0000e+000, -4.8434e-001, +5.2023e-002, -1.3091e-002, +1.8515e-003, +1.5422e-004, +0.0000e+000, +6.8298e-001, +2.5261e-003, -9.9703e-004, -1.0829e-003, +1.7688e-004, -3.1418e-005, +0.0000e+000, -3.7018e-001, +4.3234e-002, +7.2559e-003, +3.1516e-004, +2.0024e-005, -8.0581e-006, -2.3653e-006, +0.0000e+000, +1.0298e-001, -1.5086e-002, +5.6186e-003, +3.2613e-005, +4.0567e-005, -1.3925e-006, -3.6219e-007, -2.0176e-008, +0.0000e+000, -1.8364e-001, +1.8508e-002, +7.5016e-004, -9.6139e-005, -3.1995e-006, +1.3868e-007, -1.9486e-007, +3.0165e-010, -6.4376e-010 };
            double[] ap_amp = new double[55] { -1.0444e-001, +1.6618e-001, -6.3974e-002, +1.0922e+000, +5.7472e-001, -3.0277e-001, -3.5087e+000, +7.1264e-003, -1.4030e-001, +3.7050e-002, +4.0208e-001, -3.0431e-001, -1.3292e-001, +4.6746e-003, -1.5902e-004, +2.8624e+000, -3.9315e-001, -6.4371e-002, +1.6444e-002, -2.3403e-003, +4.2127e-005, +1.9945e+000, -6.0907e-001, -3.5386e-002, -1.0910e-003, -1.2799e-004, +4.0970e-005, +2.2131e-005, -5.3292e-001, -2.9765e-001, -3.2877e-002, +1.7691e-003, +5.9692e-005, +3.1725e-005, +2.0741e-005, -3.7622e-007, +2.6372e+000, -3.1165e-001, +1.6439e-002, +2.1633e-004, +1.7485e-004, +2.1587e-005, +6.1064e-006, -1.3755e-008, -7.8748e-008, -5.9152e-001, -1.7676e-001, +8.1807e-003, +1.0445e-003, +2.3432e-004, +9.3421e-006, +2.8104e-006, -1.5788e-007, -3.0648e-008, +2.6421e-010 };
            double[] bp_amp = new double[55] { +0.0000e+000, +0.0000e+000, +9.3340e-001, +0.0000e+000, +8.2346e-001, +2.2082e-001, +0.0000e+000, +9.6177e-001, -1.5650e-002, +1.2708e-003, +0.0000e+000, -3.9913e-001, +2.8020e-002, +2.8334e-002, +8.5980e-004, +0.0000e+000, +3.0545e-001, -2.1691e-002, +6.4067e-004, -3.6528e-005, -1.1166e-004, +0.0000e+000, -7.6974e-002, -1.8986e-002, +5.6896e-003, -2.4159e-004, -2.3033e-004, -9.6783e-006, +0.0000e+000, -1.0218e-001, -1.3916e-002, -4.1025e-003, -5.1340e-005, -7.0114e-005, -3.3152e-007, +1.6901e-006, +0.0000e+000, -1.2422e-002, +2.5072e-003, +1.1205e-003, -1.3034e-004, -2.3971e-005, -2.6622e-006, +5.7852e-007, +4.5847e-008, +0.0000e+000, +4.4777e-002, -3.0421e-003, +2.6062e-005, -7.2421e-005, +1.9119e-006, +3.9236e-007, +2.2390e-007, +2.9765e-009, -4.6452e-009 };
            double[] at_mean = new double[55] { +1.6257e+001, +2.1224e+000, +9.2569e-001, -2.5974e+001, +1.4510e+000, +9.2468e-002, -5.3192e-001, +2.1094e-001, -6.9210e-002, -3.4060e-002, -4.6569e+000, +2.6385e-001, -3.6093e-002, +1.0198e-002, -1.8783e-003, +7.4983e-001, +1.1741e-001, +3.9940e-002, +5.1348e-003, +5.9111e-003, +8.6133e-006, +6.3057e-001, +1.5203e-001, +3.9702e-002, +4.6334e-003, +2.4406e-004, +1.5189e-004, +1.9581e-007, +5.4414e-001, +3.5722e-001, +5.2763e-002, +4.1147e-003, -2.7239e-004, -5.9957e-005, +1.6394e-006, -7.3045e-007, -2.9394e+000, +5.5579e-002, +1.8852e-002, +3.4272e-003, -2.3193e-005, -2.9349e-005, +3.6397e-007, +2.0490e-006, -6.4719e-008, -5.2225e-001, +2.0799e-001, +1.3477e-003, +3.1613e-004, -2.2285e-004, -1.8137e-005, -1.5177e-007, +6.1343e-007, +7.8566e-008, +1.0749e-009 };
            double[] bt_mean = new double[55] { +0.0000e+000, +0.0000e+000, +1.0210e+000, +0.0000e+000, +6.0194e-001, +1.2292e-001, +0.0000e+000, -4.2184e-001, +1.8230e-001, +4.2329e-002, +0.0000e+000, +9.3312e-002, +9.5346e-002, -1.9724e-003, +5.8776e-003, +0.0000e+000, -2.0940e-001, +3.4199e-002, -5.7672e-003, -2.1590e-003, +5.6815e-004, +0.0000e+000, +2.2858e-001, +1.2283e-002, -9.3679e-003, -1.4233e-003, -1.5962e-004, +4.0160e-005, +0.0000e+000, +3.6353e-002, -9.4263e-004, -3.6762e-003, +5.8608e-005, -2.6391e-005, +3.2095e-006, -1.1605e-006, +0.0000e+000, +1.6306e-001, +1.3293e-002, -1.1395e-003, +5.1097e-005, +3.3977e-005, +7.6449e-006, -1.7602e-007, -7.6558e-008, +0.0000e+000, -4.5415e-002, -1.8027e-002, +3.6561e-004, -1.1274e-004, +1.3047e-005, +2.0001e-006, -1.5152e-007, -2.7807e-008, +7.7491e-009 };
            double[] at_amp = new double[55] { -1.8654e+000, -9.0041e+000, -1.2974e-001, -3.6053e+000, +2.0284e-002, +2.1872e-001, -1.3015e+000, +4.0355e-001, +2.2216e-001, -4.0605e-003, +1.9623e+000, +4.2887e-001, +2.1437e-001, -1.0061e-002, -1.1368e-003, -6.9235e-002, +5.6758e-001, +1.1917e-001, -7.0765e-003, +3.0017e-004, +3.0601e-004, +1.6559e+000, +2.0722e-001, +6.0013e-002, +1.7023e-004, -9.2424e-004, +1.1269e-005, -6.9911e-006, -2.0886e+000, -6.7879e-002, -8.5922e-004, -1.6087e-003, -4.5549e-005, +3.3178e-005, -6.1715e-006, -1.4446e-006, -3.7210e-001, +1.5775e-001, -1.7827e-003, -4.4396e-004, +2.2844e-004, -1.1215e-005, -2.1120e-006, -9.6421e-007, -1.4170e-008, +7.8720e-001, -4.4238e-002, -1.5120e-003, -9.4119e-004, +4.0645e-006, -4.9253e-006, -1.8656e-006, -4.0736e-007, -4.9594e-008, +1.6134e-009 };
            double[] bt_amp = new double[55] { +0.0000e+000, +0.0000e+000, -8.9895e-001, +0.0000e+000, -1.0790e+000, -1.2699e-001, +0.0000e+000, -5.9033e-001, +3.4865e-002, -3.2614e-002, +0.0000e+000, -2.4310e-002, +1.5607e-002, -2.9833e-002, -5.9048e-003, +0.0000e+000, +2.8383e-001, +4.0509e-002, -1.8834e-002, -1.2654e-003, -1.3794e-004, +0.0000e+000, +1.3306e-001, +3.4960e-002, -3.6799e-003, -3.5626e-004, +1.4814e-004, +3.7932e-006, +0.0000e+000, +2.0801e-001, +6.5640e-003, -3.4893e-003, -2.7395e-004, +7.4296e-005, -7.9927e-006, -1.0277e-006, +0.0000e+000, +3.6515e-002, -7.4319e-003, -6.2873e-004, -8.2461e-005, +3.1095e-005, -5.3860e-007, -1.2055e-007, -1.1517e-007, +0.0000e+000, +3.1404e-002, +1.5580e-002, -1.1428e-003, +3.3529e-005, +1.0387e-005, -1.9378e-006, -2.7327e-007, +7.5833e-009, -9.2323e-009 };
            double t = Math.Sin(dlat);
            int n = 9; int m = 9; int i = 0;
            double[] dfac = new double[20];
            dfac[0] = 1;
            for (i = 1; i <= 2 * n + 1; i++)
            {
                dfac[i] = dfac[i - 1] * (i);
            }
            double[,] P = new double[10, 10];
            for (i = 0; i <= n; i++)
            {
                for (int j = 0; j <= Math.Min(i, m); j++)
                {
                    double ir = Math.Floor((i - j) / 2.0);
                    double sum = 0;
                    for (int k = 0; k <= ir; k++)
                    {
                        sum = sum + Math.Pow(-1, k) * dfac[2 * i - 2 * k + 1 - 1] / dfac[k + 1 - 1] / dfac[i - k + 1 - 1] / dfac[i - j - 2 * k + 1 - 1] * Math.Pow(t, i - j - 2 * k);
                    }
                    P[i, j] = 1.0 / Math.Pow(2, i) * Math.Sqrt(Math.Pow((1 - Math.Pow(t, 2)), j)) * sum;
                }
            }
            i = 0;
            double[] aP = new double[55];
            double[] bP = new double[55];
            for (n = 0; n <= 9; n++)
            {
                for (m = 0; m <= n; m++)
                {
                    i = i + 1;
                    aP[i - 1] = P[n, m] * Math.Cos(m * dlon);
                    bP[i - 1] = P[n, m] * Math.Sin(m * dlon);
                }
            }
            // Geoidal height
            undu = 0;
            for (i = 1; i <= 55; i++)
            {
                undu = undu + (a_geoid[i - 1] * aP[i - 1] + b_geoid[i - 1] * bP[i - 1]);
            }
            //orthometric height
            double hort = dhgt - undu;
            //Surface pressure on the geoid
            double apm = 0.0;
            double apa = 0.0;
            for (i = 1; i <= 55; i++)
            {
                apm = apm + (ap_mean[i - 1] * aP[i - 1] + bp_mean[i - 1] * bP[i - 1]);
                apa = apa + (ap_amp[i - 1] * aP[i - 1] + bp_amp[i - 1] * bP[i - 1]);
            }
            double pres0 = apm + apa * Math.Cos((doy + 1 - 28) / 365.25 * 2 * Math.PI);
            // height correction for pressure
            pres = pres0 * Math.Pow((1 - 0.0000226 * hort), 5.225);
            //Surface temperature on the geoid
            double atm = 0; double ata = 0;
            for (i = 1; i <= 55; i++)
            {
                atm = atm + (at_mean[i - 1] * aP[i - 1] + bt_mean[i - 1] * bP[i - 1]);
                ata = ata + (at_amp[i - 1] * aP[i - 1] + bt_amp[i - 1] * bP[i - 1]);
            }
            double temp0 = atm + ata * Math.Cos((doy + 1 - 28) / 365.25 * 2 * Math.PI);
            //height correction for temperature
            temp = temp0 - 0.0065 * hort + 273.15;
        }



        /// <summary>
        /// 利用sanstamoinen模型计算ZHD
        /// </summary>
        /// <param name="lat">纬度，度</param>
        /// <param name="h">高度，米</param>
        /// <param name="p">压强</param>
        /// <returns></returns>
        public static double ZHD(double lat, double h, double p)
        {
            double f = 1 - 0.00266 * Math.Cos(2 * (lat * Math.PI / 180.0)) - 0.00028 * h / 1000.0;
            double zhd = 2.2768 * p / f;
            return zhd;
        }

}
}
